On Jan 8, 2010, at 12:00 AM, Christian Couder wrote: > What you could perhaps do with "git replace" or a graft is to change the > merge commit so that it has only one parent instead of 2. Thanks, also to Avery for his idea with "git .", which works well for me. For the benefit of others, here's what I've done in the end in order to get rid of the extra 100,000 commits in the old upstream branch. A very simple little script takes care of remapping the merges of the old upstream branch to the new one. It takes the output of this git log --since=2009-01-01 --format="%H %f" on each of the two upstream branches and finds corresponding commits using the first commit line. With this alignment in place, we then need the list of merge commits that need to be redirected: export BRANCHES='b1 b2 b3' git log --since=2009-01-01 --author="my name" --format="%H %P" $BRANCHES This can be fairly broad, but I didn't want BRANCHES to contain the upstream branches (even then it probably doesn't matter). I then used a little piece of trivial code to apply the alignment to the parents of potential merge commits, to generate the grafts. This is what's attached, in case anyone will find it useful.
#!/usr/bin/python # This will output a Git "grafts" file to use when a (set of) downstream branch(es) # is to switch from merging with one upstream branch to another upstream branch, without # keeping the full history of both upstream branches in the repository. # If the upstream branches contain the same history information (semantically speaking), # such as when they represent different conversions from an old CVS/SVN repository, then # this script will find an alignment between them. # The resulting grafts file will map past merges in the downstream branch to the new # upstream branch, as if the old upstream branch never existed. # If this works well, a "git filter-branch" should burn in the grafts so that they can # be removed. (This is a history-changing operation.) # See also: # http://thread.gmane.org/gmane.comp.version-control.git/136377 # recommended usage: #./make-grafts.py | sort | uniq > .git/info/grafts # set input file names upstream1 = "em-log" upstream2 = "em-new-log" mergecommits = "aq-merges" # produce files: # git checkout upstream1 # git log --since=2009-01-01 --format="%H %f">../emc/em-log # git checkout upstream2 # git log --since=2009-01-01 --format="%H %f">../emc/em-new-log # export BRANCHES='topic/b1 topic/b2 john jane master' # git log --since=2009-01-01 --author="David Reitter" --format="%H %P" $BRANCHES >../emc/aq-merges; git log --since=2009-01-01 --merges --format="%H %P" $BRANCHES >>../emc/aq-merges ################# import re import sys r1msgs = {} r1revids = {} # checkout emacs # git log --since=2009-01-01 --format="%H %f">../emc/em-log file = open(upstream1, 'r') for l in file: m = re.match("([a-f0-9]*) (.*)", l) if m: r1msgs[m.group(1)] = m.group(2) r1revids[m.group(2)] = m.group(1) file.close() r2msgs = {} r2revids = {} # checkout emacs23 # git log --since=2009-01-01 --format="%H %f" >../emc/em-new-log file = open(upstream2, 'r') for l in file: m = re.match("([a-f0-9]*) (.*)", l) if m: r2msgs[m.group(1)] = m.group(2) r2revids[m.group(2)] = m.group(1) file.close() # checkout master # export BRANCHES='23.1.undone Aquamacs22 dr-after-merge dr/dev dr/experimental dr/suedit master topic/NSAlertDialogs topic/dialogs topic/face-remapping topic/mac-support topic/menu-bar topic/minibuffer topic/option-key-remap topic/printing topic/python-mode topic/reconf topic/smart-spacing topic/spelling topic/tabbar topic/tmm topic/toolbar' # git log --since=2009-01-01 --author="David Reitter" --merges --format="%H %P" $BRANCHES >../emc/aq-merges # it's better to use all commits so we don't miss anything # git log --since=2009-01-01 --author="David Reitter" --format="%H %P" $BRANCHES >../emc/aq-merges; git log --since=2009-01-01 --merges --format="%H %P" $BRANCHES >>../emc/aq-merges def replace (revid): if revid in r1msgs: r1m = r1msgs[revid] if r1m in r2revids: r2r = r2revids[r1m] if r2r: return r2r else: print >> sys.stderr, "can't get mapping for revid "+revid+ r1m else: print >> sys.stderr, "can't find message of revid "+revid return revid # checkout master # file = open(mergecommits, 'r') for l in file: revids = l.rstrip().split(" ") if revids: # test: # revids2 = revids # for r in revids[1:]: # r2 = replace(r) # if r != r2: # revids2 = revids2 + [r2] # correct alternative revids2 = [revids[0]] + map(replace, revids[1:]) if revids != revids2: # make graft entry to write the merge such that it # looks like the merge came from the other branch print " ".join(revids2) else: print >> sys.stderr, "no remappings found for parents of merge revid "+" ".join(revids) file.close()
Attachment:
PGP.sig
Description: This is a digitally signed message part