I have gathered in this page my notes on using Github, Mercurial with Github, and Git (outside of Github) but from a Mercurial user point of view, and also from a lover-of-simplicity point of view :-).
In case of mistakes, please do not hesitate to use the current project issues to report them by simply creating a new issue on this project.
Using github
Please find some information below on Github usage.
Github is very well documented and for what is not described below, chances are the Github bootstrap articles will be helpful.
How to create static pages
To create "pages", see https://help.github.com/articles/creating-pages-with-the-automatic-generator (a bootstrap kind of doc).
Pages can be attached to:
- organizations,
- persons, like this one, or
- projects (repositories)
How to use Mercurial with a Github repository
You do not need to have Git installed in order to commit and push your changes back to Github. You will need Mercurial, obviously, and also the Dulwhich python library and the hg-git extension; which installations are covered in the first step below. Once the extension has been enabled, the rest is pretty straightforward for Mercurial users: clone, commit and push as usual.
download and install hg-git
You need to install first the dulwich python git library, then the hg-git extension.
$ mkdir -p $HOME/.hgext
$ cd $HOME/.hgext
$ whet https://pypi.python.org/packages/source/d/dulwich/dulwich-0.9.5.tar.gz
$ tar zxvf dulwich-0.9.5.tar.gz
$ rm dulwich-0.9.5.tar.gz
$ cd dulwich-0.9.5
$ ./setup.py build
$ sudo ./setup.py install
[sudo] password for cmuller:
running install
[...]
$ cd $HOME/.hgext
$ hg clone https://bitbucket.org/durin42/hg-git
$ cd hg-git/
$ hg update -C 'max(tagged())'
enable the hg-git extension in $HOME/.hgrc
[extensions]
hg-git = $HOME/.hgext/hg-git/hggit
clone the repository using Mercurial
$ hg clone git+ssh://git@github.com:cmuller/test.git
$ cd test
$ hg branch
default
$ hg bookmark
* master 1:0b48f2edc3f7
$ hg pull -u
pulling from git+ssh://git@github.com:cmuller/test.git
["git-upload-pack 'cmuller/test.git'"]
no changes found
Note: if the clone prints an error like AttributeError: 'match' object has no attribute 'traversedir'
, it is a known error in Mercurial 2.6.x: please upgrade to Mercurial >= 2.8.1.
commit some changes
$ vi README.md
$ hg status
M README.md
$ hg commit -m"test of commit using hg"
$ hg status
$ hg outgoing
comparing with git+ssh://git@github.com:cmuller/test.git
["git-receive-pack 'cmuller/test.git'"]
searching for changes
changeset: 2:2ee128a7362a
bookmark: master
tag: tip
user: Christophe Muller <...>
date: [...]
summary: test of commit using hg
push your changes back to Github
$ hg push
pushing to git+ssh://git@github.com:cmuller/test.git
searching for changes
["git-receive-pack 'cmuller/test.git'"]
Notes:
- it works. see https://github.com/cmuller/test/commit/a0b9ae9aa49118a915f1784894967f8e938ccf9e :-)
- it is interoperable with the usage of Git on the same repository. E.g.,
$ cd /tmp
$ git clone git@github.com:cmuller/test.git
$ cd test
$ git branch
* master
$ git show HEAD
commit a0b9ae9aa49118a915f1784894967f8e938ccf9e
Author: Christophe Muller <...>
Date: [...]
test of commit using hg
[...]
Using git
This is my cheatsheet for using git, with a few links to tutorials that I found useful.
Some Git equivalent to Hg commands
This is my Hg to Git cheatsheet. A complete list exist in the mercurial wiki that you might want to check in addition with the explanations on the deep differences (e.g., on branches). I advocate using only default in mercurial and master in git :-) so I won't get into these details. As for the equivalences, I have put below mostly what I use every day, so this is not an exhaustive list.
help
hg help
-> git help
In hg you basically need to know that the concept you are looking for exists or is implemented by an extension; after that, hg help
, 99% of the time, is enough and provides you with the information you need. On the other hand with git it is probably better to know beforehand what to do and only spend time in git help
at the very last resort, i.e., after google, SO, etc.
basic commands
hg init
-> git init
hg clone
-> git clone
hg add
-> git add
hg commit
-> git commit -a
hg update -u
-> git pull
hg push
-> git push
Not much differences here except the use of the staging area in git (you need to do git add
before git commit
or use the -a
option) and the git pull which on the other hand does what we want in a single command.
displaying information
hg paths
-> git remote -v
hg status
-> git status
hg diff
-> git diff
hg id
-> git rev-parse --verify --short HEAD
hg tip -p
-> git show
hg log -r 112 -p
-> git show 2a0867...
hg branches
-> git branch -a
hg branch
-> git branch
Note that if a git add
has already been performed on the modified file, the modification has moved to the staging area, so git diff --cached
should be used in order to see it. The git show
command is quite nice and easy to use. On the contrary if you really need to often get the current id, you'd better create an alias for that..
more complex (dangerous) commands
hg update -C
-> git checkout --force
hg revert
-> git reset --hard
hg backout
-> git revert
Please note that the revert-type commands are completely different between Hg and Git so please double check the documentation before using! :-)
local server
hg serve
-> git daemon --reuseaddr --base-path=. --export-all --verbose
Once hg serve
is launched, a local server is started from which it is possible to clone, pull, push, etc. (using http protocol). Similarly with the above git command, a local server is started and it is possible to clone using the git protocol, e.g.,
git clone git://<ip-address>/.git project
Some Miscellaneous Information
My git links
There are literally hundreds of docs, tutorials, posts, manuals, books etc. on Git. That probably.. shows the need :-) Below are just two links I found useful: the first one is the very minimal survival guide (but not Mercurial-user oriented) in which you will learn what is the Index, the staging area, how to push to a central repo, how to use branches, etc. The second one is not actually git-specific, it helps you ask yourself the right question and helps you choose a workflow that suits your needs.
- git - the simple guide: http://rogerdudler.github.io/git-guide/
- Git Makes Me Angry Inside: http://www.slideshare.net/emmajane/git-makes-me-angry-inside
FAQ: How to create a new repository on a server
Whereas with mercurial-server it is possible to create a repository on a server by simpy cloning from your machine to the server's URL, this is not possible with git: you have to manually at least create a directory on the server (with the right access-rights, e.g., for your group of developers) init it, and then push to it, e.g.,
- log in the server
mkdir /var/lib/git/repo.git
cd /var/lib/git/repo.git
git init --bare --shared
find . -type d -exec chmod 775 {} \;
find . -type f -exec chmod 664 {} \;
- exit
- on your PC, link to the server and then push to it, e.g.,
git remote add origin ssh://<server>/var/lib/git/repo.git
git push --all origin master
FAQ: How to change a commit log message after commit but before push
git commit --amend
How to merge a commit from a branch to master
If you have committed on a branch "b1" and want to merge this into "master", you only need to switch to the master branch, merge, and then you can push master back to the central repo, e.g.,
git checkout master
git pull
git merge b1
git push
After the merge you do not need to commit again: your changeset is already in the outgoing queue with the same metadata (author, date, log message) than the one on the branch.
How to permanently remove files or directories that have been committed and pushed
When this happen and something was committed that shouldn't have been, it can be useful to be able to log on the server and make things right again.. E.g., a clear password or confidential information, a huge data file, etc. In Subversion this operation involves using svndump and filters; in Mercurial using the convert extension; and in Git it appears to be a bit touchy as it will involve commands you probably do not use everyday (gc, prune etc.).
You can either follow the Github step-by-step tutorial here: https://help.github.com/articles/remove-sensitive-data
Or try solutions from the SO post below. This is what I did: I created a shell script starting from David Underhill's one: http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/ and adding the git reflog, fsck, repack, and prune commands as described in: http://stackoverflow.com/questions/2164581/remove-file-from-git-repository-history
Please let me know if you would need my script but basically all the commands needed are already in both David blog post and the SO answer.