Tạo chi nhánh Git với các thay đổi hiện tại


850

Tôi bắt đầu làm việc trên nhánh chủ của mình với suy nghĩ rằng nhiệm vụ của tôi sẽ dễ dàng. Sau một thời gian, tôi nhận ra rằng sẽ mất nhiều công sức hơn và tôi muốn thực hiện tất cả công việc này trong một chi nhánh mới.

Làm cách nào tôi có thể tạo một nhánh mới và mang theo tất cả những thay đổi này mà không làm bẩn chủ ?




4
Vâng, đây là những câu hỏi trùng lặp, nhưng từ ngữ khác nhau đến mức tôi nghĩ rằng điều này hữu ích để giữ. Lưu ý các từ khóa ở đây: branch current changesvs existing uncommited branch. Bất cứ ai nói tiếng Anh sẽ ngay lập tức thấy rằng họ giống nhau, nhưng công cụ tìm kiếm có thể sẽ không. Giữ câu hỏi này
Scott Bigss

Câu trả lời:


691

Nếu bạn chưa thực hiện bất kỳ cam kết nào, chỉ (1: chi nhánh) và (3: thanh toán) là đủ.
Hoặc, trong một lệnh:git checkout -b newBranch

Như đã đề cập trong git resettrang người đàn ông :

$ git branch topic/wip     # (1)
$ git reset --hard HEAD~3  # (2)  NOTE: use $git reset --soft HEAD~3 (explanation below)
$ git checkout topic/wip   # (3)
  1. Bạn đã thực hiện một số cam kết, nhưng nhận ra rằng họ còn sớm để ở trong masternhánh "". Bạn muốn tiếp tục đánh bóng chúng trong một nhánh chủ đề, vì vậy hãy tạo ra topic/wipnhánh "" hiện tại HEAD.
  2. Tua lại masterchi nhánh để thoát khỏi ba cam kết đó.
  3. Chuyển sang topic/wipchi nhánh "" và tiếp tục làm việc.

Lưu ý: do hiệu ứng "phá hủy" của git reset --hardlệnh (nó đặt lại chỉ mục và cây làm việc. Mọi thay đổi đối với các tệp được theo dõi trong cây làm việc kể từ khi <commit>bị loại bỏ), tôi muốn đi theo:

$ git reset --soft HEAD~3  # (2)

Điều này sẽ đảm bảo tôi không mất bất kỳ tệp riêng tư nào (không được thêm vào chỉ mục).
Các --softtùy chọn sẽ không chạm vào file index cũng không phải là cây làm việc tại tất cả (nhưng reset đầu đến <commit>, giống như tất cả các chế độ làm).


Với Git 2.23+ , lệnh mớigit switch sẽ tạo nhánh trong một dòng (với cùng loại reset --hard, vì vậy hãy cẩn thận với tác dụng của nó):

git switch -f -c topic/wip HEAD~3

6
Có lẽ cũng đáng lưu ý rằng đây sẽ không phải là một ý tưởng tốt nếu bạn đã cam kết tài liệu chủ đề cho chi nhánh chính của mình trong một kho lưu trữ mà người khác lấy từ đó. Hoặc ít nhất, nếu bạn cần thực hiện thiết lập lại, bạn sẽ cần nói với mọi người rằng đó là những gì bạn đang làm để những cảnh báo từ lần kéo tiếp theo của họ không gây sốc quá nhiều.
Andrew Walker

39
Lưu ý cho độc giả tương lai: đọc từ dưới lên trên (hoặc chắc chắn đọc toàn bộ). git reset --hardsẽ nuke các thay đổi của bạn và nếu chúng không được cam kết thì chúng không thể phục hồi được! Bạn có thể chỉ cầngit checkout -b …
Conrad Meyer

3
@ConradMeyer Điểm tốt. Tôi đã chỉnh sửa câu trả lời và đặt git checkout -bđầu tiên.
VonC

5
Tại sao chủ đề / chi nhánh ?? Tại sao không chỉ là tên nhánh, có một lý do đặc biệt cho việc đặt tên này? chỉ thắc mắc thôi.
Sam Stoelinga

1
@It chỉ là quy ước đặt tên không gian tên (một cách dễ dàng phân loại các nhánh, sử dụng tên nhánh phân cấp để xác định không gian tên): stackoverflow.com/a/2527436/6309 . Ví dụ, đối với các vấn đề: randyfay.com/content/... . Bạn không phải sử dụng hệ thống phân cấp khi đặt tên cho các nhánh của mình. topic_wipcũng sẽ hoạt động;)
VonC

269

Giống như đã nêu trong câu hỏi này: Git: Tạo một nhánh từ những thay đổi không được chú ý / không được cam kết trên master : stash là không cần thiết.

Chỉ dùng:

git checkout -b topic/newbranch

Bất kỳ công việc không được cam kết sẽ được đưa đến chi nhánh mới.

Nếu bạn cố gắng đẩy, bạn sẽ nhận được thông báo sau

gây tử vong: Tính năng chi nhánh hiện tại / NEWBRANCH không có chi nhánh ngược dòng. Để đẩy nhánh hiện tại và đặt điều khiển từ xa là ngược dòng, hãy sử dụng

git push --set-upstream origin feature/feature/NEWBRANCH

Chỉ cần làm như đề xuất để tạo chi nhánh từ xa:

git push --set-upstream origin feature/feature/NEWBRANCH


3
Bạn sẽ nhận được lỗi 'không có chi nhánh ngược dòng' chỉ khi bạn đẩy chi nhánh mới, không phải khi bạn cam kết công việc mới.
sam

2
@sam Tôi đã sửa đổi câu trả lời cho phù hợp
Nick Kennedy

73

Thực hiện theo các bước sau:

  1. Tạo một nhánh mới:

    git branch newfeature
    
  2. Kiểm tra chi nhánh mới: (điều này sẽ không thiết lập lại công việc của bạn.)

    git checkout newfeature
    
  3. Bây giờ cam kết công việc của bạn trên chi nhánh mới này:

    git commit -s
    

Sử dụng các bước trên sẽ giữ cho chi nhánh ban đầu của bạn sạch sẽ và bạn không phải thực hiện bất kỳ 'git reset --hard' nào.


3
'-S' làm gì trong bước 3?
Scott Biggie

12
@ScottBiggs Không cần thiết, nhưng một số người thực hành theo. Nó là viết tắt của "--signoff" và thêm tên người dùng của bạn vào cam kết cho những người trong tương lai nhìn vào nhật ký để biết rằng bạn đã từ bỏ cam kết này.
Frank Bryce

5
Câu trả lời hay, nhưng không cần -sở bước 3.
Mohammed Ali

Tôi đã học được điều gì đó mới từ nhận xét, Cảm ơn @FrankBryce
Kasparov92

30

Vì bạn chưa thực hiện bất kỳ cam kết nào, bạn có thể lưu tất cả các thay đổi của mình vào stash, tạo và chuyển sang một nhánh mới, sau đó đưa các thay đổi đó trở lại vào cây làm việc của bạn:

git stash  # save local modifications to new stash
git checkout -b topic/newbranch
git stash pop  # apply stash and remove it from the stash list

9
hoặc như VonC đã chỉ ra 'git checkout -b newbranch' và bỏ qua stash
willcodejavaforfood

@will: Tôi đã nghĩ rằng việc tạo một chi nhánh mới sẽ ghi đè lên bất kỳ thay đổi không được cam kết nào bạn có, nhưng nếu đây không phải là trường hợp, vâng, bạn có thể bỏ qua stash.
Ether

1
Tôi đã thử nó và nó hoạt động tốt, git rất chu đáo và sẽ không ghi đè lên bất kỳ thay đổi cục bộ nào
willcodejavaforfood

2
Tôi cho rằng đó là một lỗi đánh máy nhưng chỉ là một cái đầu git stash pushkhông phải là một lệnh. Bạn có lẽ sẽ muốn sử dụng git stashhoặc git stash save. Nếu bạn muốn bao gồm các tệp không bị theo dõi trong ngăn chứa, hãy sử dụng --include-untrackedtùy chọn. Tương tự, nếu bạn muốn bao gồm cả các tệp không bị theo dõi và bị bỏ qua trong ngăn chứa, hãy sử dụng --addtùy chọn thay thế.
Sáu

trong trường hợp bạn đã tạo chi nhánh rồi, điều này rất hữu ích.
Chắc chắn là

13

Để thêm các thay đổi mới vào một nhánh mới và đẩy sang điều khiển từ xa:

git branch branch/name
git checkout branch/name
git push origin branch/name

Đôi khi tôi quên thêm phần gốc để đẩy và bối rối tại sao tôi không thấy nhánh / cam kết mới trong bitbucket

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.