From: "Michael" <>


The original problem: I have a repo forked from someone else's repo. I am taking over maintenance and possible enhancements.

That's two distinct tasks (maintenance vs enhancements). Be prepared for differing approaches for each.

Also how will folks know to change to your fork, rather than the original?

Personally, I'd suggest one 'maintainers' fork which is the canonical repo, and then have a personal repo for hacks.

Have a look at how git.git works. (look also for Junio Hamano's personal repo).

As part of this, and following good coding practice, I have made branches for the various things that I have been doing.

I have also made updates to master to bring that branch up to current release; the original was based against a library (Forge) at a much older version, and I needed to both update to the current version, and update the compilation environment so that it would work inside Eclipse properly.

Make sure you do just one thing at a time, i.e. do the minimum needed at each step, and keep the code 'working'. The update to eclipse can be stage 2. Tagging each major step allows very fine grained commits. It's too easy to hurry and put three steps in one commit!

Now, I want to make things put all together.

I found that if I just did a bunch of merges, I could get something that worked with minimal conflicts (two patches that applied to almost adjacent lines messed up one merge, and the same changes in a different line order messed up a second). It wasn't that hard -- but it left a very messy looking repo.

Do define what shape you desire and what are it's key features (maintainer hat). e.g. squash all changes, always fast forward, or always neat side loops of fine grained commits, topics start at the last tag, topics start no further back than the last tag, etc. The control has been distributed to YOU. You have control of the canonical repo. Others can do what they like with their forks & clones, but you get to choose what you'll accept back and how it should look (the benign helpful dictator approach;-).

If you are getting difficulties with divergence, then try using rebase (for the branches), so that each branch is based off your last tag, and is hopefully short, so the possibility of divergence/ conflict becomes smaller.

If you can make sure you have a test machine to ensure all commits compile cleanly, and pass tests, that way you can bisect discovered failures later. (another rule).

Git has a 'master branch', a 'next' branch of generally stable fixes, and 'pu' (potential updates) that has all the rest. i.e. quite limited as a public view.

I want to clean up my repo. That is the goal.

My understanding of best practices for something that you are publishing with git for others is to clean up your commits -- rewrite history as the normal behavior.


Based on that, I am trying to learn how to rewrite history, and to see what the repo looks like when re-written.

Also determine what are the base points in the history that you _will_ keep. They are your key start points for bringing in your updates. Then determine which parts (both merges and hack commits) need to be expunged (binned). This leaves you with a view of what you need to keep. And by now a view of where they are to go.

The appears to give a reasonable display of the current flow if that helps you.

This is nice; I did not know about that. Thank you.
As I said, it looks messy.

My goal is to learn how to clean up git history.
My understanding based on what I have read/seen so far is that rebase is used for that.
My first attempt to understand rebase from the manual was a failure.

The rebase manual isn't the easiest to understand ! ! !
It's best to create a temporary repo to practice on. Try using the examples in the scm book as one option.

My second, based on what you said, did not work the way I understood it to work.

My apologies.

So right now, I would say that I don't really understand how git names the sequence of changes on a branch (from when it was split off to the head of that branch) (I thought it was just the name of the branch itself) (and I probably still don't understand 2 dot vs 3 dot vs no dot), nor how rebase actually works.

Dots: Have a look at, and the comment about it being different for 'diff' and 'log' (I learnt something there as well!)

see also 'git help revisions' - there are a number of Git guides that have man pages accessed via the normal help (try 'git help -g' - that's my one code contribution to Git so far ;-). and see also the 'git help git' page!

It's important to understand (i.e. it's hard to understand at first) that a branch is just a temporary name for a loose end of the DAG (directed acyclic graph - the backward linked list of commits, with no forward links, and no loops).

So unless you are [on] a commit on one of those loose ends, you don't have a single branch name for the commit. And once a branch tip has been merged to another branch, the tip name can be deleted without loss of the commits, and the merged commits don't know what the deleted name was.

Additional information:
1. Most of the branches are short (1 or 2 commits).
The question is then, what to do about longer branches that need many commits - special cases shouldn't be special.

2. My understanding of "cleaned up" includes squashing all branches down to a single commit when merged into master,
That is one choice. Some disagree with it. For some it's just an unthinking duplicatio of "the way it's always been done" (most Config Management techniques predate the Titanic! They are drawing office practice from the days of India ink and Koalin & linen drawing sheets!).

I like the Git practice of the 'string of pearls' (tight loop around the neck, with a single fastening/merge), so that a --first parent log shows just the topics. However it's important that the string is all pearls (quality commits that compile) rather than the usually quick fix dev rag-bag of half baked changes and undo's - that's what the rebase is for, to squash the undo's, tidy the messages, and make good. In a FOSS project it's better to take the time to make it right - you won't be paid to fix it later...

3. My understanding of cleaned up includes: When cleaned up, master should look like a bunch of fast forward, as non-fast forwards break other tools (such as bisect).
That's not quite true. What is required is that every commit is compilable. The squash/fast-forward avoids testing the intermediate steps but hides all details in one mega-commit that you'll never manage to debug. It's a choice.

Having identified your base points, either create branches from those commits (you may want multiple branches from the same point), or tag them.

Having identified the last good hacks, rebase each of your 'string of pearls' back onto the appropriate branches created above. I used the full 'git rebase --onto <A> <B> <C>' style in this phase just to make sure I have fully defined what I want to happen, rather than letting the command 'guess' what I meant (DWIM).

I use gitk extensively to give me a view of what I have. e.g. 'gitk master -30 &' in the bash prompt will give you the gitk gui window showing the last 30 commits on master, and immediately return control to bash, so you can add another, and another. Use F5 to refresh the display after a rebase, etc. I also use the 'git gui &' to allow the editing of commits if I needed. (I'm mainly on Windows, so the gui's fit the work style)

Do NOT delete any of the old branches, nor use them, until you have done the endless juggling to prettiness, then you can do the swaps

Once tidy, --force push to the maintainers repo to set out your stall.

Hope this helps.
You received this message because you are subscribed to the Google Groups "Git for 
human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
For more options, visit

Reply via email to