2010-01-22 55 views
63

Tôi có câu hỏi về newbie về Git:Git: Cách di chuyển qua lại giữa các cam kết

Tôi cần di chuyển qua lại trong lịch sử chi nhánh. Điều đó có nghĩa, tôi cần phải tải tất cả các tệp về trạng thái mà chúng đang ở trong một số bản sửa đổi cũ và sau đó tôi cần quay lại trạng thái mới nhất trong kho lưu trữ. Tôi không cần phải cam kết.

Với SVN, nó sẽ là

svn up -r800 

để có được phiên bản 800, và

svn up 

để có được đồng bộ với kho.

Tôi biết các hash của cam kết tôi muốn quay lại, vì vậy tôi cố gắng

git reset <hash> 

mà dường như để làm cho tôi ở đó. Nhưng sau đó tôi đã thử

git pull 

nhưng điều đó phàn nàn về xung đột.

Vậy cách thích hợp để di chuyển qua lịch sử của chi nhánh là gì?

Tôi đang suy nghĩ về SVN, vì vậy đừng ngần ngại chỉ cho tôi một số hướng dẫn hay. Lưu ý rằng tôi đã kiểm tra http://git.or.cz/course/svn.htmlhttp://www.youtube.com/watch?v=8dhZ9BXQgc4.

Cảm ơn, Ondra.

+1

Lưu ý phụ: Tôi đã quen với việc tránh 'git pull' hoàn toàn. Thay vào đó, tôi sử dụng 'git fetch --all' được đặt tên là' gu' trong bash, và có 'gitk' mở tất cả thời gian, xem tất cả các nhánh - xem View -> edit -> check all 4 checkboxes. Sau đó, tôi di chuyển bằng cách sử dụng 'git reset' hoặc' gist stash' + 'git co', phụ thuộc vào những gì tôi cần. –

Trả lời

59

Vâng, tôi cũng là người dùng cũ của svn và bây giờ sử dụng git cho tất cả các dự án của tôi.

Khi sử dụng git, bạn nên thay đổi cách suy nghĩ từ kiến ​​trúc client-server được sử dụng trong svn. Trong svn, mọi thay đổi cần kết nối với máy chủ. Sử dụng git, repo của bạn nằm trong thư mục làm việc. Bạn không cần kết nối cho mọi hành động repo.

Chỉ sử dụng git pushgit pull để đồng bộ hóa với repo. Hãy nghĩ về nó như sử dụng rsync hoặc bất kỳ giải pháp sao lưu nào, để làm cho hai địa điểm có cùng nội dung giống nhau. Cũng giống như bạn kết nối đĩa cứng sao lưu bên ngoài, sau đó làm cho nội dung trong nó giống với nội dung trong chính của bạn. Đó là cách sử dụng của git pullgit push.

Nếu bạn chỉ muốn quay lại và quay lại lịch sử, hãy sử dụng nó git checkout. Xem id sửa đổi bằng cách sử dụng git history. Nếu bạn đang sử dụng Linux, hãy sử dụng gitk để xem cây sửa đổi. Trong Windows, git rùa có thể hiển thị nó bằng đồ thị sửa đổi.

Để quay lại bản sửa đổi mới nhất, hãy sử dụng git checkout master. Trước khi thực hiện bất kỳ lệnh nào, hãy luôn tự mình làm git status. Lệnh này sẽ hiển thị bất cứ điều gì bạn cần biết về điều kiện repo hiện tại, và hành động nào bạn cần làm để làm cho nó đúng. Trước khi thực hiện git pullgit push, tốt hơn là đảm bảo rằng kết quả git status chứa văn bản working directory clean.

Nếu bạn cần hoàn nguyên tệp về bản sửa đổi trước đó, bạn có thể làm điều đó với git merge. Trước khi thực hiện nó vào một tập tin, kiểm tra nó trước tiên với git diff. Ví dụ: git diff rev1:rev2 filename. Nó sẽ in ra bất kỳ khác nhau giữa hai phiên bản. Thay đổi trong rev1 sẽ được thay thế bằng những thay đổi trong rev2. Vì vậy, để hoàn nguyên, rev2 sẽ cũ hơn rev1. Sau khi bạn thỏa mãn với kết quả khác, hãy thực hiện với git merge, chỉ cần thay thế diff bằng merge, tất cả các thông số khác vẫn giữ nguyên.

Tôi hy vọng điều này sẽ giúp bạn. Chìa khóa chính là để thấy rằng thư mục làm việc của bạn là repo của bạn. Hiểu được điều này sẽ giúp bạn sử dụng git với khả năng đầy đủ của nó. Chúc may mắn.

37

Bạn có thể sử dụng git checkout để thanh toán bất kỳ cam kết nào và sau đó sử dụng nó với tên chi nhánh để quay lại chi nhánh được đặt tên.

git checkout với id cam kết chứ không phải tên chi nhánh sẽ đưa bạn ra khỏi bất kỳ chi nhánh nào được đặt tên và vào cái được gọi là đầu tách rời.

Nếu bạn sử dụng git reset thì nó sẽ tự động chuyển chi nhánh của bạn về trạng thái cũ, mồ côi các cam kết gần đây hơn có thể không phải là thứ bạn muốn.

+0

'checkout' thực sự làm gì? Liệu nó có thay đổi các tệp thành trạng thái của cam kết đã cho hay không, bằng cách đảo ngược áp dụng các bản vá của các cam kết giữa trạng thái hiện tại và trạng thái của cam kết đã cho? –

+0

Tôi đã tìm thấy 'git reset' và' git reset origin'. Tôi sẽ không thực hiện bất kỳ cam kết nào, vì vậy không quan trọng liệu tôi có mất các cam kết gần đây cho đến khi nó dễ dàng phục hồi (có nghĩa là, bằng một lệnh duy nhất). –

+1

git checkout không thực hiện thay đổi vĩnh viễn. Để làm điều đó, sử dụng git merge. Xem câu trả lời của tôi. –

6

Để kiểm một phiên bản khác nhau của một tập tin, sử dụng

git checkout rev -- filename 

đâu rev thể là ID của một cam kết, tên của một chi nhánh, tên của một thẻ, hoặc một phiên bản tương đối.

Sử dụng git log, gitk để xem xét các phiên bản để xem bạn muốn phiên bản nào của tệp.

Để làm cho phiên bản này của các tập tin vĩnh viễn, bạn cần phải cam kết các file: git add filename; git commit filename

tôi sẽ không khuyên bạn nên git pull để kiểm tra phiên bản vì nó hoạt động hợp nhất - có khả năng thay đổi tình trạng hiện tại của bạn.

Bạn không cần sử dụng git reset trong trường hợp này, trừ khi bạn git add một tệp mà bạn quyết định không cam kết.

+0

jeebus ngọt phải cẩn thận khi thực hiện việc này. Đồng nghiệp của tôi đã thực hiện lệnh này để thử các thay đổi từ chi nhánh của tôi, xóa sổ khoảng một tuần giá trị công việc của tôi và đẩy nó vào repo bằng cách thực hiện việc này ... – karina

+0

Miễn là đồng nghiệp của bạn không thực hiện push -f, bạn luôn có thể hoàn nguyên cam kết của mình và khôi phục tác phẩm bị thiếu. Nếu bạn có quyền truy cập vào repo mà anh ta đã đẩy, ngay cả một lực đẩy có thể phục hồi thông qua git reflog. Ngoài ra, nếu bạn vẫn có chi nhánh của bạn, nó có thể phục hồi được. Nhưng có, bạn phải cẩn thận. –

19

Những câu trả lời khác là nhiều thông tin, nhưng tôi tin rằng đây là gần nhất với những gì OP muốn:

Thêm hai chức năng này để bạn ~/.bashrc:

# checkout prev (older) revision 
git_prev() { 
    git checkout HEAD~ 
} 

# checkout next (newer) commit 
git_next() { 
    BRANCH=`git show-ref | grep $(git show-ref -s -- HEAD) | sed 's|.*/\(.*\)|\1|' | grep -v HEAD | sort | uniq` 
    HASH=`git rev-parse $BRANCH` 
    PREV=`git rev-list --topo-order HEAD..$HASH | tail -1` 
    git checkout $PREV 
} 

Cách sử dụng:

$ git_prev 
Previous HEAD position was 7042c8a... Commit message2 
HEAD is now at d753ecc... Commit message1 

$ git_next 
Previous HEAD position was d753ecc... Commit message1 
HEAD is now at 7042c8a... Commit message2 

Lưu ý: Các lệnh này luôn nhập trạng thái detached HEAD. Nếu bạn git_prev sau đó git_next từ chi nhánh hiện đã được kiểm tra, bạn sẽ kết thúc ở phiên bản mới nhất nhưng bạn sẽ ở trạng thái HEAD tách rời. Làm git checkout BRANCH_NAME để trở lại bình thường.

+0

Một khi bạn đang làm những việc như vậy, hãy xem xét các bí danh git có thể xứng đáng. – rethab

3

Hãy thử git reflog, danh sách này cam kết và kiểm tra bạn đã thực hiện để chuyển đổi giữa các cam kết, ngay cả các cam kết bạn đã mất khi thanh toán cho cam kết trước đó.

Sau đó, bạn có thể thử git checkout <hash of a commit> để chuyển sang cam kết đó.

Hy vọng điều này sẽ hữu ích!

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