Git: 如何在提交之间来回移动

我有一个关于 Git 的新问题:

我需要在一个分支的历史中来回移动。 这意味着,我需要将所有文件恢复到它们在某个旧版本中的状态,然后我需要返回到存储库中的最新状态。我不需要承诺。

对于 SVN 来说,是的

svn up -r800

修改到800版

svn up

与存储库同步。

我知道我想要回到的提交的散列,所以我尝试了

git reset <hash>

这似乎让我得到了那里。但后来我尝试

git pull

但是,这抱怨冲突。

那么,如何正确地浏览这个分支的历史呢?

我是从 SVN 的角度来考虑的,所以不要犹豫给我指出一些好的教程。注意,我已经检查了 http://git.or.cz/course/svn.htmlhttp://www.youtube.com/watch?v=8dhZ9BXQgc4

谢谢 Ondra。

84210 次浏览

You can use git checkout to checkout any commit and then use it with a branch name to go back to a named branch.

git checkout with a commit id and not a branch name moves you off any named branch and on to what is known as a detached head.

If you use git reset then it will move your branch itself back to an old state, orphaning the more recent commits which probably isn't what you want.

Well, I'm a former svn user too, and now use git for all my projects.

When using git, you should change the way of thinking from the client-server architecture that's used in svn. In svn, every change needs a connection with server. Using git, your repo is in the working directory. You don't need a connection for every repo action.

Only use git push and git pull to synchronise with repo. Think of it like using rsync or any backup solution, to make two place have exactly same content. Just like you connect external backup hard disk, then make the content in it same with the content in your main. That's the usage of git pull and git push.

If you just want to go back and forth the history, do it using git checkout. See the revision id using git history. If you're using Linux, use gitk to see the revision tree. In Windows, tortoise git can display it using revision graph.

To get back to latest revision, use git checkout master. Before doing any command, always make yourself do git status. This command will display anything you need to know about current repo condition, and what action that you need to do to make it right. Before do git pull and git push, it's better to make sure that git status result is contain text working directory clean.

If you need to revert a file to it's previous revision, you can do it with git merge. Before doing it to a file, test it first with git diff. Ex: git diff rev1:rev2 filename. It will print out any different between two revision. Change in rev1 will be replaced by the changes in rev2. So to do revert, rev2 will be the older than rev1. After you satisfy with the diff result, do it with git merge, just replace diff with merge, all other parameters stay the same.

I hope this helps you. The main key is to see that your working dir is your repo. Understanding this will help you use git to it's full capability. Good luck.

To checkout a different version of a file, use

git checkout rev -- filename

Where rev can be the ID of a commit, the name of a branch, the name of a tag, or a relative version.

Use git log, gitk to look examine versions to see which version of the file you want.

To make this version of the file permanent, you need to commit the file: git add filename; git commit filename

I would not recommend git pull to examine versions because it does a merge -- potentially modifying your current state.

You do not need to use git reset in this case, unless you git add a file you decide not to commit.

The other answers are informative, but I believe this is closest to what the OP wants:

Add these two functions to your ~/.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
}

Usage:

$ 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

Note: These commands always enter detached HEAD state. If you git_prev then git_next from a currently checked out branch, you will end up back at the latest revision but you will be in detached HEAD state. Do git checkout BRANCH_NAME to get back to normal.

Try git reflog, this lists commits and checkouts you have done to switch between the commits, even the commits you have lost when checkout to a previous commit.

Then you can try git checkout <hash of a commit> to switch to that commit.

Hope this helps!