2012-05-11 37 views
11

Tôi rõ ràng không hiểu git chút nào. Đây là những gì tôi nhận được:git dàn dựng và cam kết giữa nhiều chi nhánh

git branch (outputs that I'm on master) 
git checkout -b foo 
echo "next line" >> file (file is an existing file) 
git add file (stages) 
git checkout master 
git status (shows that file has "next line" and is staged!!) 
git commit (commits the changes that were staged on branch foo!!) 
git checkout foo 

Đây là kicker. foo bây giờ không hiển thị bất kỳ thay đổi nào được thực hiện đối với tệp trong thư mục làm việc HOẶC được tổ chức.

Vì vậy, có vẻ như - mọi thay đổi bạn thực hiện, bao gồm sửa đổi tệp và dàn dựng, xảy ra với TẤT CẢ các chi nhánh. và khi bạn cam kết với một chi nhánh cụ thể, những thay đổi đó sẽ bị loại bỏ trên tất cả các chi nhánh khác ngoại trừ các chi nhánh bạn đã cam kết.

Đây có phải là những gì đang diễn ra không? Ai đó có thể làm điều này có ý nghĩa với tôi không? Nghe có vẻ như hành vi hoàn toàn ngớ ngẩn và rõ ràng là tôi không hiểu ý tưởng thiết kế khiến điều này trở nên hợp lý.

Sửa ví dụ rõ ràng:

$ mkdir element 
$ cd element 
$ git init 
Initialized empty Git repository in /home/dan/element/.git/ 
$ echo "one" >> one 
$ git add one 
$ git commit -m msg 
[master (root-commit) 36dc8b0] msg 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 one 
$ git checkout -b fire 
Switched to a new branch 'fire' 
$ echo "next line" >> one 
$ git checkout master 
M  one 
Switched to branch 'master' 
$ cat one 
one 
next line 
$ 

nào ràng mâu thuẫn này từ git cuốn sách ủng hộ:

This is an important point to remember: Git resets your working directory to look like the snapshot of the commit that the branch you check out points to. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it.

+2

Câu trả lời của tôi có giúp làm rõ mọi thứ không? Tôi nghĩ rằng nó có sẵn trong bản chỉnh sửa của bạn, nhưng tôi không hoàn toàn chắc chắn. – larsks

Trả lời

9

Nó không có vấn đề gì chi nhánh bạn đang ở trên khi bạn thêm một tệp, chỉ khi bạn cam kết tệp đó. Vì vậy, nếu bạn làm điều này:

git add file 
git checkout master 
git commit 

Bạn đã cam kết tệp vào nhánh chính.

Dưới đây là ví dụ hoàn chỉnh, với đầu ra. Chúng tôi bắt đầu với một kho lưu trữ mới:

$ git init 
Initialized empty Git repository in /home/lars/tmp/so/repo/.git/ 

Tại thời điểm này, chúng tôi đang ở trên nhánh master và chúng tôi chưa bổ sung bất kỳ tập tin. Hãy thêm một tập tin:

$ date > file1 
$ cat file1 
Fri May 11 13:05:59 EDT 2012 
$ git add file1 
$ git commit -m 'added a file' 
[master (root-commit) b0764b9] added a file 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 file1 

Tuyệt vời, bây giờ chúng tôi có một chi nhánh (master) với một cam kết. Hãy tạo chi nhánh mới:

$ git checkout -b foo 
Switched to a new branch 'foo' 
$ git branch 
* foo 
    master 
$ ls 
file1 

Bây giờ chúng tôi sẽ thêm một dòng vào file1.

$ date >> file1 
$ git status 
# On branch foo 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
#  modified: file1 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

Điều này cho thấy tệp đã được sửa đổi nhưng chưa được dàn dựng. Hãy giai đoạn tập tin và cam kết nó:

$ git add file1 
$ git commit -m 'made a change' 
[foo 761bed9] made a change 
1 files changed, 1 insertions(+), 0 deletions(-) 

Và chạy lại git status:

$ git status 
# On branch foo 
nothing to commit (working directory clean) 

Tại thời điểm này, các tập tin trông như thế này:

Fri May 11 13:05:59 EDT 2012 
Fri May 11 13:07:36 EDT 2012 

Nếu chúng ta chuyển về chi nhánh master, chúng tôi sẽ xem phiên bản trước của tệp mà không có dòng thứ hai:

$ git checkout master 
Switched to branch 'master' 
$ cat file1 
Fri May 11 13:05:59 EDT 2012 

Các thay đổi đối với một tệp được phân lập với chi nhánh mà chúng đã được cam kết.

Trong ví dụ cập nhật của bạn, điều này ...

$ git checkout master 

... không tạo ra một lỗi vì vào thời điểm này, phiên bản của 'một' trong cả hai masterfire là giống hệt nhau. Những thay đổi trong thư mục làm việc sẽ áp dụng tốt cho cả hai phiên bản.

+1

Có - nếu bạn làm việc trên một nhánh nguyên tử để cam kết mọi thứ hoạt động như trong ví dụ này và điều đó có ý nghĩa với tôi. Nếu bạn sửa đổi và có thể giai đoạn mà không cam kết và sau đó chuyển đổi chi nhánh, sau đó bạn nhập trạng thái kỳ lạ này đã xảy ra trong bài viết đầu tiên của tôi. Liệu đạo đức có đơn giản không bao giờ chuyển đổi chi nhánh mà không cam kết? Tuy nhiên: nếu tôi làm điều này theo một hướng khác và làm việc trên máy chủ và chuyển sang nhánh, nó sẽ cho tôi một lỗi: 'lỗi: Bạn có thay đổi cục bộ đối với 'một'; không thể chuyển nhánh.' Không biết tại sao tôi không nhận được lỗi này hoạt động theo một hướng khác. – djechlin

+1

Tệp có thực sự được theo dõi trước khi chạy 'git add' không? Bạn có thể làm lại câu hỏi của mình bằng cách sử dụng kho lưu trữ mẫu hiển thị các lệnh và đầu ra thực tế không? Nói chung, nó là phổ biến để cam kết hoặc [stash] (http://git-scm.com/book/en/Git-Tools-Stashing) thay đổi của bạn trước khi chuyển đổi chi nhánh. – larsks

+1

Câu hỏi đã chỉnh sửa để hiển thị toàn bộ cuộc hội thoại thay vì chỉ các lệnh. Tôi sẽ nhìn vào stash - có vẻ như tôi không hiểu cách các nhánh "nông" thực sự ở trong git. Tôi không hiểu tại sao git cho phép tôi thực hiện một thanh toán bẩn mặc dù. – djechlin

2

Khu vực dàn dựng aka chỉ mục là phổ biến cho tất cả các chi nhánh, giải thích quan sát của bạn

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