简体   繁体   中英

Git equivalent to hg update

Below is a small example with Mercurial and similarly with Git. I cannot understand how to make a hg update with Git:

I have a small Mercurial setup with 4 commits - where I step back one commit

hg init
echo "1" > a.txt; hg commit -A -m "1. commit" a.txt
echo "2" >> a.txt; hg commit -m "2. commit" a.txt
echo "3" >> a.txt; hg commit -m "3. commit" a.txt
echo "4" >> a.txt; hg commit -m "4. commit" a.txt
hg update -r 3
thg # or hg view`

This gives this picture

THG

Note that I see all four commit - ie both the pre-history and the following commit(s)

Let me try to do the same example using Git

git init
echo "1" > a.txt; git add a.txt; git commit  -m "1. commit" a.txt
echo "2" >> a.txt; git commit -m "2. commit" a.txt
echo "3" >> a.txt; git commit -m "3. commit" a.txt
echo "4" >> a.txt; git commit -m "4. commit" a.txt # gives for me [master 57bb375]

Let me see the commits:

git log --graph --pretty=format:'%h -%d %s (%cr) <%an>' 

 * 57bb375 - (HEAD, master) 4. commit (14 minutes ago) <Peter Toft>
 * 724a493 - 3. commit (14 minutes ago) <Peter Toft>
 * bb38732 - 2. commit (14 minutes ago) <Peter Toft>
 * 879c593 - 1. commit (15 minutes ago) <Peter Toft>

Good - four commits as expected. Let me go back one commit (similar as hg update)

git checkout 724a493

What about the git log now?

git log --graph --pretty=format:'%h -%d %s (%cr) <%an>' 

 * 724a493 - (HEAD) 3. commit (19 minutes ago) <Peter Toft>
 * bb38732 - 2. commit (19 minutes ago) <Peter Toft>
 * 879c593 - 1. commit (19 minutes ago) <Peter Toft>

gitk will also just show the first 3 commits?

So "git checkout" is NOT just similar to "hg update". Where are the following commit(s)?

hg update -r 3 is giving you an automatic branch head to which you could continue committing. In git, checkout takes you to the right commit, but doesn't give you a new branch head. If you want that you can say

git checkout -b new_branch_name 724a493

of course using whatever you like as the name. If you don't use -b , as in your question, you get into the state of a detached HEAD ... which is exactly the difference between hg update -r 3 and git checkout 724a493 . Note the message Git prints when you do your checkout (from me running your example):

Note: checking out '2ffb5e0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 2ffb5e0... 3. commit

To put it simply, the 57bb375 commit did not go anywhere when you ran git checkout 724a493 . The behavior you're seeing is simply that git log only shows commits that are ancestors of the checked out commit.

In Mercurial terms, git log is the same as

$ hg log -r ::.

which means "show me commits that are ancestors of . , ie, the working copy parent revision". To get the equivalent of hg log in Git, simply run

$ git log --all

This little difference is a key feature for Git since it allows you to pull in commits from lots of other repositories without seeing them by default. It is only if you checkout a branch (or a commit in your case) that you will see the commits you've downloaded into your repository.

Another solution variant: Adding

[alias]
    restore = "!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep ^D | cut -f 2); }; f"

then "git restore" will move me one commit backwards in time without requiring me to make an artificial branch.

If I want to return to the master branch

git checkout master

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM