Git equivalents of most common Mercurial commands?

43,751

Solution 1

The Git-HG rosetta stone is not bad

There are a few other gotchas between the two not mentioned there. This list was cribbed from my own blog post when I went the other way (git -> hg).

Hg .hgignore, syntax: glob is the same behaviour as git's .gitignore.

Git .git/config, ~/.gitconfig, use git-config to modify the values
Hg .hg/hgrc, ~/.hgrc, use hg help -c config

Git git commit -v<br> Hg hg diff | less; hg commit

Git gitk<br> Hg hg view, or thg from [TortoiseHg][1]

Git git gui<br> Hg Mercurial doesn't ship GUI to select changesets, only console hg record command.

Git git rebase<br> Hg hg rebase. For git rebase --interactive there's hg histedit, or Mercurial Queues

Git git push URL ; git remote add origin URL<br> Hg hg push URL; $EDITOR .hg/hgrc ; [paths] default = URL

Git gitk, git log origin/master..HEAD<br> Hg hg outgoing

Git git format-patch RANGE<br> Hg hg email -m filename -o

Git git add . ; Note the dot
Hg hg add ; No dot needed.

Git git checkout REVISION-KEY<br> Hg hg update CHANGESET


Just to fill the blanks, some of the most useful commands from Mercurial:

Hg hg record
Git git add -p; git commit

Hg hg inc [URL]
Git No real equivalent. You can only do equivalent of hg pull; hg log -r .:

Hg hg out URL
Git Please add if you know how.

For merge conflict resolution, the hg resolve command in Mercurial has a few options that change the behaviour:

Hg hg resolve -m FILE (marks the file as having been resolved by manually fixing up the conflict problem)
Git git add FILE

Hg hg resolve -u FILE marks the file as having been unresolved
Git git reset HEAD FILE to unstage the file

Hg hg resolve -l (lists files with resolved/unresolved conflicts)
Git git status - files that merged cleanly are added to the index automatically, those that are not have conflicts

Hg hg resolve FILE (after a merge, attempts to re-merge the file)
Git no equivalent for re-merging that I know of.

Solution 2

Note: one of the biggest difference between Git and Mercurial is the explicit presence of the index or staging area.

From Mercurial for Git User:

Git is the only DistributedSCM that exposes the concept of index or staging area. The others may implement and hide it, but in no other case the user is aware nor has to deal with it.

Mercurial's rough equivalent is the DirState, which controls working copy status information to determine the files to be included in the next commit. But in any case, this file is handled automatically.
Additionally, it is possible to be more selective at commit time either by specifying the files you want to commit on the command line or by using the RecordExtension.

If you felt uncomfortable dealing with the index, you are switching for the better ;-)


The trick is, you really need to understand the index to exploit fully Git. As this article from May 2006 reminds us then (and it is still true now):

“If you deny the Index, you really deny git itself.”

Now, that article contains many commands which are now simpler to use (so do not rely on its content too much ;) ), but the general idea remains:

You are working on a new feature and starts to make minor modifications on a file.

# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile

At this point, your next commit will embark 2 minor modifications in the current branch

# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work

$ git commit

Only records the changes added to the staging area (index) at this point, not the major changes currently visible in your working directory.

$ git branch newFeature_Branch
$ git add myFile

The next commit will record all the other major changes in the new branch 'newFrature_Branch'.

Now, adding interactively or even splitting a commit are features available with Mercurial, through the 'hg record' command or other extensions: you will need to install RecordExtension, or the CrecordExtension.
But this is not part of the normal workflow for Mercurial.

Git views a commit as a series of "file content changes", and let you add those changes one at a time.
You should study that feature and its consequences: Most of Git power (like the ability to easily revert a merge (or bisect the problem, or revert a commit), contrary to Mercurial) comes from that "file content" paradigm.


tonfa (in in profile: "Hg dev, pythonist": figures...) chimed in, in the comments:

There's nothing fundamentally "git-ish" in the index, hg could use an index if it was deemed valuable, in fact mq or shelve already do part of that.

Oh boy. Here we go again.

First, I am not here to make one tool looks better than another. I find Hg great, very intuitive, with a good support (especially on Windows, my main platform, although I work on Linux and Solaris8 or 10 too).

The index is actually front and center in the way Linus Torvalds works with a VCS:

Git used explicit index updates from day 1, even before it did the first merge. It's simply how I've always worked. I tend to have dirty trees, with some random patch in my tree that I do not want to commit, because it's just a Makefile update for the next version

Now the combination of the index (which is not a notion seen only in Git), and the "content is king" paradigm makes it pretty unique and "git-ish":

git is a content tracker, and a file name has no meaning unless associated to its content. Therefore, the only sane behavior for git add filename is to add the content of the file as well as its name to the index.

Note: the "content", here, is defined as follows:

Git's index is basically very much defined as

  • sufficient to contain the total "content" of the tree (and this includes all metadata: the filename, the mode, and the file contents are all parts of the "content", and they are all meaningless on their own!)
  • additional "stat" information to allow the obvious and trivial (but hugely important!) filesystem comparison optimizations.

So you really should see the index as being the content.

The content is not the "file name" or the "file content" as separate parts. You really cannot separate the two.
Filenames on their own make no sense (they have to have file content too), and file content on its own is similarly senseless (you have to know how to reach it).

What I'm trying to say is that git fundamentally doesn't allow you to see a filename without its content. The whole notion is insane and not valid. It has no relevance for "reality".

From the FAQ, the main advantages are:

  • commit with a fine granularity
  • help you to keep an uncommited modification in your tree for a reasonably long time
  • perform several small steps for one commit, checking what you did with git diff, and validating each small step with git add or git add -u.
  • allows excellent management of merge conflicts: git diff --base, git diff --ours, git diff --theirs.
  • allows git commit --amend to amend only the log message if the index hasn't been modified in the meantime

I personally think this behavior shouldn't be the default, you want people to commit something that is tested or at least compiled

While you are right in general (about the "tested or compiled" part), the way Git allows you for branching and merging (cherry-picking or rebasing) allows you to commit as often as you want in a temporary private branch (pushed only to remote "backup" repository), while re-doing those "ugly commits" on a public branch, with all the right tests in place.

Solution 3

Mercurial:

hg init . # start a project in the current directory
hg addremove # look for any added or deleted files
hg commit -m "comment" # commit any uncomitted changes
hg status # what have i changed since the last commit?

Git Equivalents:

git init
git add -A
git commit -am "comment" # -a is not necessary along with the above add -A
git status

Solution 4

It is roughly the same, without addremove:

git init # Start a project in the current directory
git status # Displays both changes and added/removed files
git commit -m "comment" # commit any uncommited changes

However, these are commands you would use when working alone. You get into the neat stuff when you want to merge your changes with other people's work with git pull and git push, and related commands.

Share:
43,751
Admin
Author by

Admin

Updated on June 02, 2020

Comments

  • Admin
    Admin about 4 years

    I've been using Mercurial but would like to do a quick demo of Git.

    What are the Git equivalents of:

    hg init . # start a project in the current directory
    hg addremove # look for any added or deleted files
    hg commit -m "comment" # commit any uncomitted changes
    hg status # what have i changed since the last commit?
    
  • warnabas
    warnabas almost 15 years
    and to top it off, use "git show" (same as "git diff" I believe) to see what you have changed since last commit.
  • Dustin
    Dustin almost 15 years
    "git show" (with no args) shows you the changes in the last commit. "git diff" shows you the changes since the last commit.
  • u0b34a0f6ae
    u0b34a0f6ae almost 15 years
    I (and I think most git users) use git add -u more than -A; -u will stage changes for all tracked files, ignoring new untracked files.
  • tonfa
    tonfa almost 15 years
    There's nothing fundamentally "git-ish" in the index, hg could use an index if it was deemed valuable, in fact mq or shelve already do part of that. I personnaly think this behaviour shouldn't be the default, you want people to commit something that is tested or at least compiled.
  • tonfa
    tonfa almost 15 years
    but addremove adds new untracked files :)
  • quark
    quark over 14 years
    The real equivalent for git rebase is in fact hg rebase. Queues are a more complex thing (they do more than rebase at the cost of more work by the user). Git has several external tools to do what queues do (guilt, stacked Git, etc.)
  • Michal aka Miki
    Michal aka Miki over 14 years
    I disagree with that git status is equivalent to hg status. I am new in Hg and have not managed to get hg`s status work similarly as that of Git.
  • VonC
    VonC over 13 years
    About what is in a Git index, see stackoverflow.com/questions/4084921/…
  • Benbob
    Benbob about 13 years
    Perhaps this should be a wiki.
  • tonicebrian
    tonicebrian over 12 years
    For gitk there is a graphical clone for Mercurial, hgview (note that it is different from the "hg view" command)
  • MordechayS
    MordechayS over 12 years
    A small suggestion: swapping the Hg and Git text around (as it's Git for Mercurial users)
  • Face
    Face over 10 years
    Hg outgoing is not equivalent to a git log filter. It simply lists what changes would be pushed to the given URL without having to pull from there first to update the remote pointers. Git gui's functionality is a graphical one, and as such it should be compared to TortoiseHg's hunk selection/shelve feature.
  • Denilson Sá Maia
    Denilson Sá Maia over 10 years
    Although hg record is not very user-friendly, hg crecord (from crecord extension) is a curses-based text UI that is extremely easy to use.
  • Ben Moss
    Ben Moss over 7 years
    @ozzy432836 I haven't used Hg for years now, but I think those are the resolve equivalents. FWIW the default action of hg resolve is one of the reasons I prefer git. By default hg resolve destroys your nicely manually resolved merge if you pass it no arguments!
  • Ruslan Yushchenko
    Ruslan Yushchenko over 7 years
    In Mercurial your last commit (before push) acts like git's index. You can amend it, roll it back, change commit message or finalize it by changing it's phase to public.