TheShed

Git Cheats

Category: Programming
#Git #Source Control

A post to capture Git related goodness. The secret sauce? Branch early and often but merge and kill branches too.

Updated: 2014-10-03

Fragments

Basics

Create a directory with your project

e.g. ~\project

git init

To create a Git repro. If you want a bare repro (i.e. because you're going to push to it from somewhere else) use git --bare init.

git add <filename.c>

To add a file(s) to the repro or to stage a file (staged files are like a snapshot of what you're going to commit before you actually commit (commit to committing!). This means you can stage files as you work on them and then commit an atomic piece of work.

Git will flag untracked files. If you want to ignore files, add them to a .gitignore file. For example:

\output

Will ignore anything in the \output subdirectory. You might want to ignore *.jpg for example, but binary files and Git is a whole other story (search for GitMedia for example).

git status

To see what's what.

git commit -m "Commit message"

Commit whatever is staged to the repro.

git rm <file>

remove a file (from repro) and local directory

git log

Get useful stuff from git like a log...

...loads of options like for example

git log -p -2

which shows the diffs (-p) for the last 2 (-2) commits.

git log --pretty=oneline

What a GUI? use:

gitk

Remote Repositories

git remote -v

Show remote repositories

git remote show <remotename>

extra info about remotename

git remote add <remotename> <URL>

Connect to a remote

git fetch <remotename>

Grab everything from a remote but won't merge

git pull

Works if you have a branch setup to track a remote branch (although in my tests it just worked??!?) got

git push <remotename> <branchname>

Push your changes back to the remote - but beware if someone else has also pushed!

git clone <url>

Creates a local repro in a new directory with remotename=origin

git remote rm <remotename>

remove remote

note: you can use UNC paths on windows, but use forward slahes, i.e.

git remote add origin //home-server/git/Crowmarsh/Crowmarsh.git

Tagging

git tag -a v0.1 -m "Tag: version 0.1 alpha"

Tag with annotation (v0.1)

then:

git tag show v0.1

Important: git won't push tags to remote servers automagically. In that sense they're like branches, so you do:

git push <remotename> <tag>

e.g. git push origin v0.1

git push --tags

will push all tags...!

Branching

Branches are lightweight. Effectively they are a pointer to the git object that represents the commit.

git branch <branchname>

Creates a new branch pointing to the last commit.

git checkout <branchname>

Switches to the branch. Switches is a significant piece of terminology; think of it as switching rather than checking out.

git branch 
git branch -v

Details of branches....

Basic Merging

First, checkout the branch you want to merge into, then:

git merge <branchname>

If you get something like CONFLICT (content): Merge conflict in readme.txt then you'll need to open the file(s) and edit to resolve the conflicts.

Then commit as normal...

Note that merge does a 3-way merge between the two latest branch snapshots and the most recent common ancestor of the two.

git commit -a -m "Message"

Mark has a useful blog post covering why you should

git fetch
git merge

rather than

git pull

Remote Branches

There's a branch on your remote repros to, typically initially this is origin/master (i.e. the origin of your remote and the master (or HEAD) branch). If you do work locally and then push to the remote all is fine. Except that is, if someone else has pushed to the remote in the meantime so that origin/master is now ahead. To you need to fetch...

git fetch origin

You can checkout a local tracking branch that git knows is related to a remote branch, and so automagically pushes changes to the right place without you having to tell it.

git checkout --track <remote>/<branch>

If you have a local repo and want to push to a (bare) remote repo, use

git remote add <name> <url>
git push --set-upstream -u <name> <branch>

Rebasing

There are two ways to integrate changes from one branch to another. merge (see above) and rebasing. Instead of the 3-way merging, rebasing takes all the changes committed on one branch and replays them (rebases) on another.

Switch to branch then

git rebase master

to rebase from master onto the branch you checked out.

Merging

Merging from a remote branch (i.e. two developers have pushed changes to the server in the same branch).

git fetch
git rebase origin/master

See http://stackoverflow.com/questions/7200614/how-to-merge-remote-master-to-local-branch

Tracking

Tracking branches means Git is aware of the relationship between a local branch and a remote branch, for example, when tracked git status automagically tells you whether you're ahead or behind the remote branch.

git checkout --track origin/development

Will checkout a remote branch (origin/development) locally and set the relationship between them. Alternatively, you can set a tracking relationship when pushing your local branch. i.e.

git push -u origin development

git branch -vv

Provides details of tracked relationships known to Git.

Misc

Fix a detached head:

git checkout master

From http://stackoverflow.com/questions/10228760/fix-a-git-detached-head

Overwrite local files

If you want to overwrite local, uncommitted, files you can use:

git fetch --all
git reset --hard origin/master

(From Stackoverflow)

Reference material