chi nhánh chuyển đổi git mà không loại bỏ thay đổi cục bộ


181

Được rồi, giả sử một ngày nào đó chúng ta thực hiện một loạt các sửa đổi và khi chúng ta thực hiện chúng, chúng ta nhận thấy chúng ta đang làm việc sai chi nhánh.

Làm thế nào chúng ta có thể buộc git chuyển đổi các nhánh mà không loại bỏ các thay đổi cục bộ .

Có lẽ tôi sẽ giải quyết vấn đề này một cách ngây thơ trong khi chờ đợi câu trả lời, nhưng tôi muốn biết liệu có một quy trình đúng như tôi đang nói dối nếu tôi nói điều này không xảy ra với tôi trước đây ...

  • Sao lưu thay đổi repo
  • git reset --hard
  • git checkout right-branch
  • Khôi phục các thay đổi
  • git commit -m "changes"

Câu trả lời:


342

Có một loạt các cách khác nhau tùy thuộc vào khoảng cách của bạn và nhánh bạn muốn sử dụng.

Hãy mắc một sai lầm kinh điển:

$ git checkout master
... pause for coffee, etc ...
... return, edit a bunch of stuff, then: oops, wanted to be on develop

Vì vậy, bây giờ bạn muốn những thay đổi này, mà bạn chưa cam kết master, sẽ được thực hiện develop.

  1. Nếu bạn không có một developbài viết nào, phương pháp này là tầm thường:

    $ git checkout -b develop
    

    Điều này tạo ra một developchi nhánh mới bắt đầu từ bất cứ nơi nào bạn đang có. Bây giờ bạn có thể cam kết và các công cụ mới là tất cả trên develop.

  2. Bạn một develop. Xem nếu Git sẽ cho phép bạn chuyển đổi mà không làm gì:

    $ git checkout develop
    

    Điều này hoặc sẽ thành công, hoặc phàn nàn. Nếu nó thành công, thật tuyệt! Chỉ cần cam kết. Nếu không ( error: Your local changes to the following files would be overwritten ...), bạn vẫn có nhiều lựa chọn.

    Đơn giản nhất có lẽ là git stash(như tất cả những người trả lời khác đánh bại tôi khi nhấp vào postnói). Chạy git stash savehoặc git stash push, 1 hoặc chỉ đơn giản git stashlà viết tắt của save/ push:

    $ git stash
    

    Điều này cam kết mã của bạn (vâng, nó thực sự thực hiện một số cam kết) bằng cách sử dụng một phương thức không phân nhánh-y kỳ lạ. Các cam kết mà nó thực hiện không phải là "trên" bất kỳ nhánh nào nhưng hiện được lưu trữ an toàn trong kho lưu trữ, vì vậy bây giờ bạn có thể chuyển đổi các nhánh, sau đó "áp dụng" stash:

    $ git checkout develop
    Switched to branch 'develop'
    $ git stash apply
    

    Nếu mọi việc suôn sẻ, và bạn thích kết quả, thì bạn nên git stash dropbỏ qua. Điều này xóa tham chiếu đến các cam kết không phân nhánh-y kỳ lạ. (Chúng vẫn còn trong kho lưu trữ và đôi khi có thể được truy xuất trong trường hợp khẩn cấp, nhưng đối với hầu hết các mục đích, bạn nên xem xét chúng đã biến mất vào thời điểm đó.)

Các applybước thực hiện việc kết hợp với những thay đổi cất giấu, sử dụng máy móc thiết bị hợp nhất cơ bản mạnh mẽ của Git, cùng một loại điều nó sử dụng khi bạn làm hòa trộn chi nhánh. Điều này có nghĩa là bạn có thể nhận được "xung đột hợp nhất" nếu nhánh bạn đang làm việc do nhầm lẫn, đủ khác với nhánh mà bạn dự định làm việc. Vì vậy, nên kiểm tra kết quả một cách cẩn thận trước khi bạn cho rằng stash được áp dụng sạch sẽ, ngay cả khi chính Git không phát hiện ra bất kỳ xung đột hợp nhất nào.

Nhiều người sử dụng git stash pop, đó là tay ngắn cho git stash apply && git stash drop. Điều đó tốt cho đến nay, nhưng điều đó có nghĩa là nếu ứng dụng dẫn đến một mớ hỗn độn và bạn quyết định rằng bạn không muốn tiếp tục con đường này, bạn không thể lấy lại dễ dàng. Đó là lý do tại sao tôi khuyên bạn nên tách riêng apply, kiểm tra kết quả, dropchỉ khi / khi hài lòng. (Điều này tất nhiên giới thiệu một điểm khác trong đó bạn có thể nghỉ giải lao khác và quên đi những gì bạn đã làm, quay lại và làm sai , vì vậy đó không phải là một cách chữa trị hoàn hảo.)


1 Các savetrong git stash savelà động từ cũ để tạo một stash mới. Phiên bản Git 2.13 đã giới thiệu động từ mới để làm cho mọi thứ phù hợp hơn popvà để thêm nhiều tùy chọn hơn cho lệnh tạo. Phiên bản Git 2.16 chính thức không dùng động từ cũ (mặc dù nó vẫn hoạt động trong Git 2.23, đây là phiên bản mới nhất tại thời điểm tôi đang chỉnh sửa này).


3
Điều gì xảy ra nếu tôi muốn chuyển sang một chi nhánh khác mà không cam kết với chi nhánh hiện tại (ví dụ: các thay đổi chưa kết thúc) và sau đó chuyển trở lại để tiếp tục?
stt106

@ stt106: bạn vẫn phải cam kết, nhưng bạn có thể làm điều đó, như trong này và câu trả lời khác, thông qua git stashđể các cam-cho git stash, bạn sẽ có hai cam kết cho mỗi mục stash, trong một bất thường sắp xếp-là trên không chi nhánh. Tuy nhiên, ngoại trừ các trường hợp đặc biệt rất ngắn hạn, tôi thường thích thực hiện một cam kết bình thường. Bạn có thể git reset --softhoặc git reset --mixedsau đó, hoặc sử dụng git commit --amendđể đẩy nó sang một bên, khi bạn quay lại làm việc trên nhánh đó. (Trong Git hiện đại, bạn cũng có thể sử dụng git worktree add, đó có thể là một giải pháp thậm chí còn tốt hơn.)
torek

"Điều này sẽ thành công hoặc phàn nàn." Đó sẽ là lý do cho sự thành công hoặc lỗi khi thực hiện kiểm tra?
nanocv


tất cả các thay đổi cục bộ của tôi sẽ bị mất khi tôi chuyển đổi với các bước trên Tôi đang ở trong <a> chi nhánh và thực hiện các thay đổi của mình và tôi muốn chuyển sang <b> chi nhánh và đẩy tất cả các thay đổi của mình vào đó. khi tôi đang thực hiện git stash và chuyển sang các nhánh khác, nó kéo tất cả các tệp của <b> nhánh và các thay đổi cục bộ của tôi bị mất
Mukul Munjal

38

Sử dụng git stash

git stash

Nó đẩy các thay đổi đến một ngăn xếp. Khi bạn muốn kéo chúng trở lại sử dụng

 git stash apply

Bạn thậm chí có thể kéo các mục cá nhân ra. Để hoàn toàn thổi bay stash:

 git stash clear

7
Lệnh cuối cùng có lẽ nên được git stash drop; git stash clearsẽ xóa sạch toàn bộ ngăn xếp, bao gồm cả các ngăn không liên quan đến tập lệnh này.
Leland

15
  • git stash để lưu các thay đổi không được cam kết của bạn
  • git stash list để liệt kê các stash chưa được lưu của bạn
  • git stash apply stash@{x} trong đó x có thể là 0,1,2..không có stash mà bạn đã thực hiện

4

Bạn có thể:

  • Sử dụng git stashđể tạm gác những thay đổi của bạn hoặc,

  • Tạo một nhánh khác và cam kết các thay đổi của bạn ở đó, sau đó hợp nhất nhánh đó vào thư mục làm việc của bạn

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.