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