git: Chuyển nhánh và bỏ qua mọi thay đổi mà không cam kết


318

Tôi đã làm việc trên một chi nhánh git và sẵn sàng thực hiện các thay đổi của mình, vì vậy tôi đã thực hiện một cam kết với một thông điệp cam kết hữu ích. Sau đó, tôi đã lơ đãng thực hiện các thay đổi nhỏ đối với mã không đáng lưu giữ. Bây giờ tôi muốn thay đổi chi nhánh, nhưng git cho tôi,

lỗi: Bạn có các thay đổi cục bộ thành "X"; không thể chuyển ngành.

Tôi có thể thay đổi chi nhánh mà không cam kết không? Nếu vậy, làm thế nào tôi có thể thiết lập này? Nếu không, làm thế nào để tôi thoát khỏi vấn đề này? Tôi muốn bỏ qua những thay đổi nhỏ mà không cam kết và chỉ thay đổi chi nhánh.


1
Tôi tin rằng điều này chỉ xảy ra khi những thay đổi được dàn dựng cho cam kết nhưng không được cam kết? kiểm tra git chỉ hoạt động tốt để thay đổi chi nhánh nếu bạn chưa dàn dựng các tệp bằng cách sử dụng git add hoặc tương tự.
Jeremy Wall

1
Xin chào Jeremy, ý của bạn là 'dàn dựng' là gì? Buộc người dùng phải cam kết tập tin trước khi thay đổi chi nhánh dường như không phải là một quy trình công việc tuyệt vời. Ví dụ: nếu tôi đang ở trong kho lưu trữ chính và nhanh chóng muốn kiểm tra một cái gì đó trong một nhánh. Tôi phải cam kết mã cho chủ trước, thậm chí nó là mã được viết một nửa! Bạn đang nói rằng thực sự, nó có thể kiểm tra một chi nhánh trong tình huống này?
Daniel Farrell

@boyfarrell Bạn có thể sử dụng 'Git stash' để tạm thời lưu các thay đổi mà không cần cam kết.
Howiecamp


1
khi bạn chuyển sang một nhánh mà không thực hiện các thay đổi trong nhánh cũ, git sẽ cố gắng hợp nhất các thay đổi với các tệp trong nhánh mới. Nếu việc hợp nhất được thực hiện mà không có bất kỳ xung đột nào, các nhánh xoay sẽ thành công và bạn có thể thấy những thay đổi trong nhánh mới. Nhưng nếu xảy ra xung đột, bạn sẽ nhận được error: You have local changes to '<filename>'; cannot switch branches.và chi nhánh sẽ không thay đổi. bạn có thể làm git checkout -m <branch-name>để hợp nhất các xung đột và kiểm tra chi nhánh và tự giải quyết xung đột hoặc git checkout -f <branch-name>bỏ qua các thay đổi.
samad montazeri

Câu trả lời:


400

Bạn cần một trạng thái sạch sẽ để thay đổi chi nhánh. Thanh toán chi nhánh sẽ chỉ được phép nếu nó không ảnh hưởng đến 'tệp bẩn' (như Charles Bailey nhận xét trong các bình luận).

Nếu không, bạn nên:

  • bỏ qua thay đổi hiện tại của bạn hoặc
  • reset --hard HEAD (nếu bạn không ngại mất những thay đổi nhỏ đó) hoặc
  • checkout -f (Khi chuyển nhánh, tiến hành ngay cả khi chỉ mục hoặc cây làm việc khác với HEAD. Cái này được sử dụng để loại bỏ các thay đổi cục bộ.)

Hoặc, gần đây hơn:

Tiến hành ngay cả khi chỉ mục hoặc cây làm việc khác với CHÍNH.
Cả chỉ mục và cây làm việc đều được khôi phục để phù hợp với mục tiêu chuyển đổi.

Điều này khác với git switch -m <branch-name>, điều này kích hoạt sự hợp nhất ba chiều giữa nhánh hiện tại, nội dung cây làm việc của bạn và nhánh mới được thực hiện: bạn sẽ không mất công việc của mình theo cách đó.


34
"Bạn cần một trạng thái sạch sẽ để thay đổi chi nhánh." chỉ đúng nếu thay đổi chi nhánh ảnh hưởng đến 'tệp bẩn'.
CB Bailey

10
Đối với phương pháp stash, tôi đã gõ "git stash save", "git checkout otherbranch", rồi cuối cùng là "git stash pop".
Venkat D.

1
Hiện tại tôi không thấy thông báo lỗi này và những thay đổi tôi đã thực hiện trên một nhánh sẽ hiển thị trên nhánh kia khi tôi thực hiện "trạng thái git". có gì thay đổi?
Senthil A Kumar

2
cảm ơn. kiểm tra -f là những gì tôi cần. tôi đã thiết lập lại git - hãy git sạch -f git checkout mybranch -f
nologo

1
Đây là một điều tuyệt vời mà Git đã hoàn toàn sai khi vi phạm định nghĩa cơ bản của một nhánh. Không giống như nhánh git có nghĩa là hai không gian làm việc hoàn toàn khác nhau được phân tách từ một kho lưu trữ.
nehem

125

Nếu bạn muốn loại bỏ các thay đổi,

git checkout -- <file>
git checkout branch

Nếu bạn muốn giữ những thay đổi,

git stash save
git checkout branch
git stash pop

10
Thật vậy, những gì Romerun nói (sẽ hoàn thành): git stash save(khi đang làm việc ở chi nhánhY) sau đó git checkout branchXlàm một cái gì đó, git add/commit -mv.v. git checkout branchYgit stash popđể lấy lại stash
Highmastdon

2
Co le vậy. Tôi có một tình huống mặc dù tôi muốn làm gì câu trả lời nói, nếu tôi hiểu đúng: stash thay đổi, chuyển từ Y sang X, sau đó bật thay đổi và cam kết chúng trên X.
Ben Klein

1
lưu ý rằng git stash savehiện không được ủng hộgit stash push
Argento

Bí danh này đơn giản hóa trường hợp giữ thay đổi khi thay đổi chi nhánh.
Tom Hale

62

tốt, nó nên

git stash save
git checkout branch
// do something
git checkout oldbranch
git stash pop

5
Đúng, stash là toàn cầu, không phải là chi nhánh cụ thể, nếu tôi bỏ qua pop sau khi chuyển nhánh, tôi sẽ nhận được stash giống như trên các nhánh khác
Aditya Mittal

6
Cần lưu ý git stashsẽ mặc định làgit stash save
Charlie-Greenman

Cảm ơn bạn, nó rất hữu ích cho tôi
Govind Kumar


16

Lưu ý rằng nếu bạn đã hợp nhất các chi nhánh từ xa hoặc có các xác nhận cục bộ và muốn quay lại TRÊN từ xa, bạn phải thực hiện:

git reset --hard origin/HEAD

HEAD một mình sẽ chỉ đề cập đến cam kết / hợp nhất cục bộ - nhiều lần tôi đã quên rằng khi đặt lại và kết thúc với "kho lưu trữ của bạn là X cam kết trước .." khi tôi hoàn toàn có ý định nuke TẤT CẢ các thay đổi / cam kết và quay lại chi nhánh từ xa .


9

Nếu bạn đã thay đổi các tệp mà Git cũng cần thay đổi khi chuyển nhánh, nó sẽ không cho phép bạn. Để loại bỏ các thay đổi làm việc, sử dụng:

git reset --hard HEAD

Sau đó, bạn sẽ có thể chuyển đổi chi nhánh.


9

Không có câu trả lời nào trong số này giúp tôi vì tôi vẫn có các tệp không bị theo dõi ngay cả sau khi đặt lại và bỏ rác. Tôi phải làm:

git reset --hard HEAD
git clean -d -f

4

chuyển sang một nhánh mới mất thay đổi:

git checkout -b YOUR_NEW_BRANCH_NAME --force

chuyển sang một chi nhánh hiện có mất thay đổi:

git checkout YOUR_BRANCH --force

4

Trả lời dễ dàng:

là để kiểm tra một chi nhánh

git checkout -f <branch_name>

Buộc kiểm tra một chi nhánh đang yêu cầu git bỏ tất cả các thay đổi bạn đã thực hiện trong chi nhánh hiện tại và kiểm tra chi nhánh mong muốn.

hoặc trong trường hợp bạn đang kiểm tra một cam kết

git checkout -f <commit-hash>


"nghĩ rằng tôi có thể thay đổi chi nhánh mà không cần cam kết. Nếu vậy, làm thế nào tôi có thể thiết lập điều này? Nếu không, làm thế nào để tôi thoát khỏi vấn đề này?"

Câu trả lời là Không , đó chính là triết lý của Git mà bạn theo dõi tất cả các thay đổi và mỗi nút (nghĩa là cam kết) phải được cập nhật với những thay đổi mới nhất bạn đã thực hiện, trừ khi bạn Tất nhiên là một cam kết mới.


Bạn quyết định giữ thay đổi?

Sau đó cất chúng bằng cách sử dụng

git stash

và sau đó để hủy bỏ các thay đổi của bạn trong nhánh mong muốn, hãy sử dụng

git stash apply

sẽ thay đổi bạn nhưng cũng giữ chúng trong hàng đợi. Nếu bạn không muốn giữ chúng trong ngăn xếp, hãy bật chúng bằng cách sử dụng

git stash pop

Đó là tương đương applyvà sau đódrop


2

Đóng thiết bị đầu cuối, xóa thư mục nơi dự án của bạn, sau đó sao chép lại dự án của bạn và voilá.


2
git không được thiết kế để thúc đẩy bạn xóa dự án và sao chép lại! Nếu bạn muốn có được phiên bản mới nhất từ ​​nguồn gốc, bạn chỉ cần reset --hard!
Ahmed Nour Jamal El-Din

2

Nếu bạn muốn giữ các thay đổi và thay đổi nhánh trong một dòng lệnh đơn

git stash && git checkout <branch_name> && git stash pop

1

Di chuyển các thay đổi không được cam kết sang một chi nhánh mới

Tôi đã tạo một .gitconfigbí danh cho điều này:

[alias]
spcosp = !"git stash push && git checkout \"$@\" && git stash pop --index #"

Để thay đổi new-branch-name, sử dụng:

git spcosp new-branch-name

Và bất kỳ thay đổi tập tin và chỉ mục không cam kết sẽ được giữ lại.


1

kiểm tra git -f your_branch_name

git checkout -f your_branch_name

nếu bạn gặp khó khăn trong việc hoàn nguyên các thay đổi:

git checkout .

nếu bạn muốn xóa các thư mục và tệp không bị theo dõi:

git clean -fd

0

Để chuyển sang chi nhánh khác mà không thực hiện các thay đổi khi git stash không hoạt động. Bạn có thể sử dụng lệnh dưới đây:

kiểm tra git -f tên chi nhánh

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.