forked from dustin/bindir
-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-reroot
executable file
·65 lines (53 loc) · 2.12 KB
/
git-reroot
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env python
"""
Pick up all of the changes of a tree and reparent them elsewhere.
Given some arbitrary sequence of commits, all of the changes from the
sequence will be applied in the new location.
This has an effect similar to rebase, but is purely content driven.
Each commit is recorded with the exact state the tree was in, but
repositioned on top of the current tree. This is likely the wrong
tool for whatever job you're hoping to use it on.
It will never have a conflict, but at the consequence of sometimes
providing you with diffs that don't make a lot of sense.
Read more about this here:
<http://dustin.github.com/2009/01/06/git-reroot.html>
"""
import os
import sys
import commands
import subprocess
def run_cmd(cmd):
exitstatus, outtext = commands.getstatusoutput(cmd)
if exitstatus != 0:
raise RuntimeException("Command failed.")
return outtext
def cleanup_log(commit, c):
return c[:c.index("--" + commit + "--")]
def recommit(commit_log, onto):
commit, tree, an, ae, ad, cn, ce, cd, log = commit_log
log = cleanup_log(commit, log)
env = {'GIT_COMMITTER_NAME': cn, 'GIT_COMMITER_EMAIL': ce,
'GIT_AUTHOR_NAME': an, 'GIT_AUTHOR_EMAIL': ae,
'GIT_COMMITER_DATE': cd, 'GIT_AUTHOR_DATE': ad,
'PATH': os.getenv("PATH")}
args=["git", "commit-tree", tree, '-p', onto]
p = subprocess.Popen(args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
stdout, stderr = p.communicate(log)
sys.stderr.write(stderr)
p.wait()
if p.returncode != 0:
sys.exit(p.returncode)
return stdout.strip()
if __name__ == '__main__':
log = run_cmd('git log --reverse --pretty=format:"%H%n%T%n%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b--%H--%x00" '
+ sys.argv[1])
h = run_cmd("git rev-parse HEAD")
commits=[s.split("\n", 8) for s in log.split("\0\n")]
done=0
for commit in commits:
h = recommit(commit, h)
done += 1
sys.stdout.write(" %d/%d\r" % (done, len(commits)))
sys.stdout.flush()
print "The newly created history is available as " + h