Re: git-log - hide parent (was: merging two equivalent branches)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]