Git Quickstart

Marc Dutoo edited this page Jun 13, 2014 · 34 revisions
Clone this wiki locally

Basics : SCM as usual

At its simplest, git may be seen as source version control with your own source repository within your development environment, where you have to commit before contributing back to the shared source repository.

So to work on EasySOA, set up git and then :

# get the source code from the shared repository
git clone git@github.com:easysoa/EasySOA.git
# then code some things...
# then to contribute them back, first update to the latest version
git pull
# and if no problem, commit and push them to the shared repository
git commit
git push

Good practices

Solving merge conflicts

A conflict happens when the same file has seen different commits in parallel on its local and remote repository. Sure, it can be solved by doing a merge and committing it, as shown further below. But the better alternative is to avoid merges as much as possible.

To avoid merges as much as possible, use rebase instead of pull, in order to remove your commits since your last update (but keep your changes in files !) : git rebase origin. This is so useful that some are talking about making it the default behaviour. You can already make it your default by adding in your .git/config :

branch.autosetuprebase = always

This also keeps the commit history simple. It is almost mandatory when working less often than other committers in order to avoid big merges for few & small commits. However, you may want to avoid it unless necessary if you're the main committer or you're working temporarily on a big set of consistent commits, such as when doing a comprehensive refactoring.

This being said that in praise of rebase, here is the full list of alternatives to solve merge conflicts :

  • if you've not committed yet, put uncommitted work temporarily aside, and "pop" it back once (auto)merge is done : stash - git stash save, git stash pop
  • if you've not committed yet but have a non-empty staging area (ex. because of a merge), you can empty it by doing a reset : git reset. BEWARE you'll have to ex. merge again.
  • if you've committed but not pushed yet, use a rebase as said above, or delete your last commit(s): soft reset - git reset --soft HEAD~1.
  • if you've already pushed, add another commit that reverts changes back : revert - git revert HEAD

Visual tools

You can get visual help for merging by using : git mergetool and installing one of the visual tools it lists, such as Meld.

The real deal : the peer-to-peer way

When at some point you want to get more benefits from git, you have to understand how it works - that's peer-to-peer. So let's throw clone & pull out of the window from now, and do it back again from the start by rather managing "remote" repository references by hand.

getting a repo :

mkdir easysoa-myrepo  
cd easysoa-myrepo  
git init  
git remote add origin git@github.com:easysoa/easysoa-myrepo.git 

(if it doesn't exist yet, first create easysoa-myrepo in github in the easysoa organization)

update and commit :

git fetch origin  
git merge origin/master  
# check whether there is any merge work left to do :  
git status  
# commit all (for finer control, use add / remove) and enter a commit message :  
git commit -a  
git push origin  

forking someone else's repo

(only do that if you don't have the rights on said repo)

first fork it as your own on github, then get your forked one, and finally add the upstream remote :

git remote add upstream git@github.com:someoneelse/hisrepo.git  

when updating, first fetch and merge from the upstream remote :

git fetch upstream
git merge upstream/master  

to ask for contributing your commits to the upstream, do a Pull Request on them.

Back to basics

Now how does all that play with basic pull & push ? Simple : Pulling is the same as doing a fetch & merge. So you can do simpler updates with :

git pull
git push

For this to work if you first used init & add remote, your preferred branch must be known, either by creating the repo using clone instead of git & remote add

git clone git@github.com:easysoa/easysoa-myrepo.git 

or by adding in your .git/config

[branch "master"]
    remote = origin
    merge = refs/heads/master

Repo refactoring

moving a repo

from your account to the easysoa organization : clone --bare, then push --mirror (see http://help.github.com/moving-a-repo/ )

existing clones can be pointed to the new repo using :

git remote set-url <name> <url>  

merging different repos with history

Go in the project where you want to merge another project. Then execute the following commands (<projectName> is the name of the project to merge):

git remote add -f <projectName> <projectUrl>
git merge -s ours <projectName>/master
git read-tree --prefix=<projectName>/ -u <projectName>/master
git commit
git push origin

FAQ

  • how to mirror a repo : git clone --mirror git@github.com:easysoa/EasySOA.git and how to keep it up to date : git fetch -q --all (thanks redmine
    • git can't work because of an index-lock file in .git/ : with EGit doesn't work, with shell just remove it

Tips

  • To delete all the files marked as 'deleted' on the same time, use this command : 'git ls-files --deleted | xargs git rm'
  • To reset the index but keep changes : git reset