How to merge massive formatting-only commits between git branches

*** As always, first backup everything (your git working directory etc.) ***

Let’s assume formatting changed in branch A, and you’re working in branch B

To make life easier, prepare two git clones, the other one is checked out
with branch A (in dir gitA), the other one with branch B (in dir gitB).
You need to have both branches in gitB up-to-date, so:

gitB> checkout A
gitB> git pull
gitB> checkout B
gitB> git pull

Let’s assume the formatting-only megacommit has hashcode AAAA and the commit
before that has hashcode BBBB. You can check the latest commits to
branch A like this:

gitA> git log | less

First, merge A to B until the last commit before the formatting-only commit.

gitB> git merge BBBB

Do the usual merge-stuff and commit. Do not push. For later analysis store
the changed filenames:

gitB> git diff --name-only A > ../diffsbeforemerge

Close Eclipse or other clever software that is holding to your git working clone.


gitB> git clean -d -x -f .

Copy all files to a safe place, e.g.

gitB> cd ..
xxxx> tar cf gitB.tar gitB

Create another tar file without .git directory:

xxxx> cp gitB.tar gitB-nogit.tar
xxxx> tar --delete -f gitB-nogit.tar gitB/.git

Merge the formatting-only megacommit (hashcode AAAA):

xxxx> cd gitB
gitB> git merge AAAA

Don’t worry about any conflicts… Just copy over the old files:

gitB> cd ..
xxxx> tar xf gitB-nogit.tar

At this point, format all source codes with the same formatter as in branch A,
e.g. by starting Eclipse and importing the correct formatter and then selecting
all projects and ‘Source/Format’.


xxxx> cd gitB
gitB> git add *
gitB> git commit -m "Synchronized formatting with branch A."

Now it is a good time to check what was changed before you push your changes
anywhere. Remember that you have the backup of the situation before merging,
so you can just wipe away the gitB directory and extract the tarball gitB.tar.

You can check that the formatting-only-merge did not add any new diffs to

gitB> git diff --name-only A > ../diffsaftermerge
gitB> diff -u ../diffsbeforemerge ../diffsaftermerge

On Git

I am starting to like Git. Check out what it is here.

This is more like a note-to-myself kind of post, but also a crash introduction how to replace a shared CVS repository with Git.

Assume you have Git binaries installed and a directory full of files (maybe tracked with CVS, Subversion, some other version control tool, or not at all – it really doesn’t matter). Jump into the directory and type:

> git init .

Now you have a Git repository. You can do local commits, you can clone the repository with the ‘git clone’ -command, and so on. However, I want to have a central point, which is backed up, and which is a “hub” for the other repositories. An example is a “Documents” -directory, which I just want to:

a) store “the state” on a server,
b) sync between different machines,
c) store the history of changes,
d) store the checksum of each file,
e) be able to do simple ‘git push’ and ‘git pull’ without extra magic

Here is how to set it up (check out the command explanations from man pages if you care):

On the server, create a bare Git repository:

> mkdir ~/Documents.git
> cd ~/Documents.git
> git init --bare .

On a machine with the existing Documents directory:

> cd ~/Documents
> git init .
> git add *.txt
> git commit -m "Added all old .txt -files."
> git remote add server ssh://server/home/user/Documents.git
> git push server master
> git branch --track m2 server/master
> git checkout m2
> git branch -d master
> git branch -m m2 master

On all other machines, simply:

> git clone server ssh://server/home/user/Documents.git Documents
> cd Documents
> vim foo.txt
> git add foo.txt
> git commit -m "Edited foo.txt."
> git push

After these steps, you can just keep doing ‘git commit’, ‘git push’ and ‘git pull’ on all of the machines, and the “hub” at the server is easy to backup.