2010-04-02 24 views
742

Bối cảnh: Tôi đang làm việc trên máy chủ để thêm tính năng đơn giản. Sau một vài phút tôi nhận ra nó không đơn giản như vậy và tốt hơn nên làm việc trong một chi nhánh mới.Git: Tạo chi nhánh từ các thay đổi không được tổ chức/không được cam kết trên trang chính

Điều này luôn xảy ra với tôi và tôi không biết cách chuyển sang một chi nhánh khác và thực hiện tất cả những thay đổi không được sửa đổi này với tôi để lại chi nhánh chính sạch sẽ. Tôi nghĩ git stash && git stash branch new_branch đơn giản sẽ thực hiện điều đó nhưng đây là những gì tôi nhận được:

~/test $ git status 
# On branch master 
nothing to commit (working directory clean) 

~/test $ echo "hello!" > testing 

~/test $ git status 
# On branch master 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

~/test $ git stash 
Saved working directory and index state WIP on master: 4402b8c testing 
HEAD is now at 4402b8c testing 

~/test $ git status 
# On branch master 
nothing to commit (working directory clean) 

~/test $ git stash branch new_branch 
Switched to a new branch 'new_branch' 
# On branch new_branch 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 
Dropped refs/[email protected]{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b) 

~/test $ git s 
# On branch new_branch 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

~/test $ git checkout master 
M testing 
Switched to branch 'master' 

~/test $ git status 
# On branch master 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

Bạn có biết nếu có bất kỳ cách nào thực hiện điều này?

+0

Mặc dù có một giải pháp đơn giản cho vấn đề của bạn, bạn có thể chỉ định trong những kết quả bạn nhận được khác với những gì bạn muốn? – Gauthier

+1

bằng cách thực hiện các câu trả lời ở trên hoặc ở dưới cùng, các thay đổi không được đề cập là trên cả chính và nhánh mới. Tôi chỉ muốn họ trên nhánh mới, vì vậy tôi có thể kiểm tra tổng thể và làm việc trên một thứ khác mà không cần phải thay đổi những điều này xung quanh – knoopx

+1

xem câu trả lời đã chỉnh sửa của tôi. Bạn cần phải cam kết các thay đổi cục bộ của bạn trên nhánh mới nếu bạn muốn thanh toán một trình chủ thuần túy. Thay đổi cục bộ chỉ là sự khác biệt giữa HEAD hiện tại và tệp của bạn trên đĩa. Những thay đổi này trên các tệp cục bộ không được phiên bản, bạn cần phải nói với git để lưu chúng ở đâu đó nếu bạn muốn truy xuất chúng sau này. – Gauthier

Trả lời

884

Không cần phải giấu.

git checkout -b new_branch_name 

không chạm vào các thay đổi cục bộ của bạn. Nó chỉ tạo nhánh từ HEAD hiện tại và đặt HEAD ở đó. Vì vậy, tôi đoán đó là những gì bạn muốn.

--- Chỉnh sửa để giải thích kết quả của tổng thể thanh toán ---

Bạn bối rối vì checkout master không loại bỏ những thay đổi của bạn?

Vì những thay đổi chỉ là cục bộ, git không muốn bạn mất chúng quá dễ dàng. Khi thay đổi nhánh, git không ghi đè các thay đổi cục bộ của bạn. Kết quả của số checkout master của bạn là:

M testing 

, có nghĩa là tệp công việc của bạn không sạch. git đã thay đổi HEAD nhưng không ghi đè lên các tệp cục bộ của bạn. Đó là lý do tại sao trạng thái cuối cùng của bạn vẫn hiển thị các thay đổi cục bộ của bạn, mặc dù bạn đang ở trên master.

Nếu bạn thực sự muốn hủy thay đổi cục bộ, bạn phải thực hiện thanh toán với -f.

git checkout master -f 

Vì thay đổi của bạn chưa bao giờ được cam kết, bạn sẽ mất chúng.

Cố gắng quay lại chi nhánh của bạn, cam kết thay đổi của bạn, sau đó thanh toán lại chính.

git checkout new_branch 
git commit -a -m"edited" 
git checkout master 
git status 

Bạn sẽ nhận được một thông điệp M sau khi kiểm tra đầu tiên, nhưng sau đó không nữa sau khi checkout master, và git status nên thấy không có file sửa đổi.

--- Chỉnh sửa để làm sáng tỏ sự nhầm lẫn về thư mục (tập tin địa phương) ---

làm việc Trong câu trả lời cho nhận xét đầu tiên của bạn, thay đổi địa phương chỉ là ... tốt, địa phương. Git không tự động lưu chúng, bạn phải bảo nó để lưu chúng sau này. Nếu bạn thực hiện thay đổi và không cam kết rõ ràng hoặc giấu chúng, git sẽ không phiên bản chúng. Nếu bạn thay đổi HEAD (checkout master), các thay đổi cục bộ sẽ không được ghi đè vì chưa được lưu.

+0

Đây là cách tôi luôn làm. Nó hoạt động chính xác như bạn muốn. – synic

+0

dude, tôi đã bỏ lỡ điểm quan trọng này. Tôi nghĩ rằng tôi có lý do tại sao điều này xảy ra và tại sao git rõ ràng là không thể bỏ qua những thay đổi (mà không cần phải loại bỏ) nếu tôi không cam kết đầu tiên. Cảm ơn bạn: D – knoopx

+22

Điều khó hiểu ở đây là trang của người đàn ông git nói rằng 'git checkout'“ Cập nhật các tệp trong cây đang hoạt động để khớp với phiên bản trong chỉ mục hoặc cây được chỉ định. ”. Điều đó giả định những thay đổi của bạn trong hệ thống tệp của bạn sẽ là * GONE * sau đó. Không có cơ hội lấy lại chúng. Ngay cả khi bạn nói rằng họ sẽ không làm như vậy, điều này vẫn để lại một cảm giác rất xấu. Tôi không tin điều này * chút nào *. Tài liệu thực sự là xấu hoặc hành vi mặc định của git thực sự nguy hiểm. Người ta không cần phải tin tưởng vào một số "tự động" heuristic để phát hiện rằng trong trường hợp này bạn không muốn mất những thay đổi của bạn. – Evi1M4chine

46

Hãy thử:

git stash 
git checkout -b new-branch 
git stash apply 
+5

Điều này khác với việc chỉ thực hiện 'git checkout -b new-branch'? –

+0

Tôi không nghĩ đó là khi câu trả lời ban đầu được viết, nhưng tôi có thể sai. Thật không may vì hoàn cảnh làm việc của tôi, tôi đã sử dụng lực lượng cho một vài năm qua vì vậy tôi không thể chứng thực tính chính xác của nó bây giờ. –

+2

Hoặc thay vì hai bước cuối cùng: git stash branch chi nhánh mới – rethab

12

Hai điều bạn có thể làm:

git stash -u 
git branch sillyname [email protected]{0} 

hoặc

git checkout -b sillyname 
git commit -am "silly message" 
git checkout - 

(git stash -u < - các -u nghĩa là nó cũng có những thay đổi unstaged)

(git checkout - < - các dấu gạch ngang là lối tắt cho nhánh trước bạn đang truy cập)

4

Nếu bạn đang sử dụng ứng dụng khách GitHub Windows (như tôi) và bạn đang gặp phải những thay đổi không được cam kết mà bạn muốn chuyển sang chi nhánh mới, bạn có thể chỉ cần "Crate nhánh mới" qua ứng dụng GitHub . Nó sẽ chuyển sang nhánh mới được tạo và duy trì các thay đổi của bạn.

enter image description here

+0

ngăn chặn các thay đổi trước khi tạo nhánh mới để nó không giữ chúng (phiên bản 223 trên Mac OS) –

Các vấn đề liên quan