From: "Michael" <keybou...@gmail.com>
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
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
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
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
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.
appears to give a reasonable display of the current flow if that
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
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
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
The question is then, what to do about longer branches that need many
commits - special cases shouldn't be special.
1. Most of the branches are short (1 or 2 commits).
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
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 https://groups.google.com/d/optout.