mhagger / git-imerge Goto Github PK
View Code? Open in Web Editor NEWIncremental merge for git
License: GNU General Public License v2.0
Incremental merge for git
License: GNU General Public License v2.0
It would be very helpful if git-imerge
was available via PyPI so it could be installed via pip
or similar tools.
If trying to merge an non-existent branch, git-imerge fails very ungracefully:
$ git imerge start --name=mergebranch --goal=rebase-with-history --first-parent inexistentbranch
fatal: Not a valid object name inexistentbranch
Traceback (most recent call last):
File "/home/eddy/bin/git-imerge", line 2796, in <module>
main(sys.argv[1:])
File "/home/eddy/bin/git-imerge", line 222, in wrapper
return f(*args, **kw)
File "/home/eddy/bin/git-imerge", line 2665, in main
options.name, options.goal, 'HEAD', options.branch,
File "/home/eddy/bin/git-imerge", line 1768, in initialize
merge_base = check_output(['git', 'merge-base', '--all', tip1, tip2]).splitlines()
File "/usr/lib/python2.7/subprocess.py", line 544, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['git', 'merge-base', '--all', 'HEAD', 'inexistentbranch']' returned non-zero exit status 128
Before trying to operate on the branch to be merged, it should be checked if it is known and gracefully inform the user the branch does not, if that's the case.
I'm in a situation where the resolution of a conflict would result in an empty commit. When I git add
the file, and then do git imerge continue
I get the message Commit 121-302 was not blocking the frontier.
. When doing git imerge continue
, I get the very same conflict presented again.
I've worked around this with git commit --allow-empty
, but it would be nicer to have git imerge skip
, in analogy to git rebase --skip
.
I believe this will be nice to add presentation of git-imerge by https://asciinema.org/ to easily show features.
Hi,
I was wondering how git-imerge interacts with rerere, and general comments about the use of both at the same time, and possible problems and such.
Thanks
Not many ideas on how to debug it for you to figure out the problem, but I get something like this:
Attempting automerge of 11-5...success.
Attempting automerge of 11-6...success.
Attempting automerge of 40-6...success.
Autofilling 11-6...success.
Autofilling 12-6...success.
Autofilling 13-6...success.
Autofilling 14-6...success.
Autofilling 15-6...success.
Autofilling 16-6...success.
Autofilling 17-6...success.
Autofilling 18-6...success.
Autofilling 19-6...success.
Autofilling 20-6...success.
Autofilling 21-6...success.
Autofilling 22-6...success.
Autofilling 23-6...success.
Autofilling 24-6...success.
Autofilling 25-6...success.
Autofilling 26-6...success.
Autofilling 27-6...success.
Autofilling 28-6...success.
Autofilling 29-6...success.
Autofilling 30-6...success.
Autofilling 31-6...success.
Autofilling 32-6...success.
Autofilling 33-6...success.
Autofilling 34-6...success.
Autofilling 35-6...success.
Autofilling 36-6...success.
Autofilling 37-6...success.
Autofilling 38-6...success.
Autofilling 39-6...success.
Autofilling 40-5...unexpected failure.
Attempting automerge of 11-5...success.
Adding some prints about what throws the error
if i1 < block.len1 and i2 < block.len2:
print self.blocks[i]
self.blocks[i] = block[:i1, :i2]
shrunk_block = True
print self.blocks[i]
gets me
MergeState('tn-path', goal=u'rebase')[10:41,4:7]
MergeState('tn-path', goal=u'rebase')[10:40,4:5]
at every loop. non the wiser I tried to manually run the code that threw the error;
knirch@traktor:~/source/mergedir/proj ((5d15d6a...))$ git checkout -f 5d15d6aaa94f6c2fc99faa305f6e8c942335cf
HEAD is now at 5d15d6a... Merge commit 'eb229220f5d3d2cf249962f216f051e0b3507669' into HEAD
knirch@traktor:~/source/mergedir/proj ((5d15d6a...))$ git -c rerere.enabled=false merge 6058897a2a80f43dc1b73d00048461935f0a9922
CONFLICT (modify/delete): subdir/subdir/source.c deleted in HEAD and modified in 6058897a2a80f43dc1b73d00048461935f0a9922. Version 6058897a2a80f43dc1b73d00048461935f0a9922 of subdir/subdir/source.c left in tree.
Automatic merge failed; fix conflicts and then commit the result.
Haven't grokked your code enough to make even an educated guess.
(also, unused variables tricked me in auto_outline_frontier)
except UnexpectedMergeFailure, e:
# One of the merges that we expected to succeed in
# fact failed.
i1, i2 = e.i1, e.i1
print e.i1, e.i2
merge_frontier.remove_failure(e.i1, e.i2)
return self.auto_outline_frontier(merge_frontier)
i1, i2 = e.i1, e.i1 made me think I had spotted an error, but since i1 and i2 aren't used.. :)
I ran git checkout service-worker-apps && git imerge start --first-parent --goal=rebase-with-history --name service-worker-apps lkgr^
and got the result at https://github.com/jyasskin/chromium/tree/service-worker-apps.broken.imerge. This was quite possibly my mistake, but I think it's inconsistent with the result I would have gotten from git rebase lkgr^
. Specifically, imerge
appears to have put the lkgr
branch on top of the service-worker-apps
branch, while a rebase
would have put service-worker-apps
on top of lkgr
.
When imerge finishes its rebase-with-history it appends the git commit messages with an information fact about the change, but it appends this blindly against the bottom of the commit message, rather than injecting it above any footers that happen to be present.
In this instance, the footers are being used by the Gerrit code review tool and trigger gerrit into creating duplicate review entries.
Removed collections from AgreementItem
Change-Id: I3587019fabd05348dfcf3f89cd9421f24c3f9c1f
(rebased-with-history from commit 70b69c80d9f5131cdc023d39dd341d11f67d43be)
Is it possible to specify the start point of the commits in branch to be merged (the upstream
argument of git-rebase
).
I'm asking because my work is on a stable branch of upstream and now I'm going to rebase my commits to a newer stable branch from upstream. The two branches share many commits doing the same things. And I only want to rebase my commits.
While doing an git imerge rebase I get the following error:
Attempting automerge of 11-29...failure.
Attempting automerge of 1-1...success.
Attempting automerge of 1-16...success.
Attempting automerge of 1-23...success.
Attempting automerge of 1-27...success.
Attempting automerge of 1-29...success.
Attempting automerge of 11-29...failure.
Attempting automerge of 6-29...failure.
Attempting automerge of 4-29...success.
Attempting automerge of 5-29...success.
Attempting automerge of 6-1...success.
Attempting automerge of 6-15...success.
Attempting automerge of 6-22...success.
Attempting automerge of 6-26...success.
Attempting automerge of 6-28...failure.
Attempting automerge of 6-27...failure.
Attempting automerge of 11-26...success.
Autofilling 1-29...success.
Autofilling 2-29...success.
Autofilling 3-29...success.
Autofilling 4-29...success.
Autofilling 5-1...success.
Autofilling 5-2...success.
Autofilling 5-3...success.
Autofilling 5-4...success.
Autofilling 5-5...success.
Autofilling 5-6...success.
Autofilling 5-7...success.
Autofilling 5-8...success.
Autofilling 5-9...success.
Autofilling 5-10...success.
Autofilling 5-11...success.
Autofilling 5-12...unexpected conflict. Backtracking...
Autofilling 1-29...success.
Autofilling 2-29...success.
Autofilling 3-29...success.
Autofilling 4-1...success.
Autofilling 4-2...success.
Autofilling 4-3...success.
Autofilling 4-4...success.
Autofilling 4-5...success.
Autofilling 4-6...success.
Autofilling 4-7...success.
Autofilling 4-8...success.
Autofilling 4-9...success.
Autofilling 4-10...success.
Autofilling 4-11...success.
Autofilling 4-12...unexpected conflict. Backtracking...
Autofilling 1-29...success.
Autofilling 2-29...success.
Autofilling 3-1...success.
Autofilling 3-2...success.
Autofilling 3-3...success.
Autofilling 3-4...success.
Autofilling 3-5...success.
Autofilling 3-6...success.
Autofilling 3-7...success.
Autofilling 3-8...success.
Autofilling 3-9...success.
Autofilling 3-10...success.
Autofilling 3-11...success.
Autofilling 3-12...success.
Autofilling 3-13...success.
Autofilling 3-14...success.
Autofilling 3-15...success.
Autofilling 3-16...success.
Autofilling 3-17...success.
Autofilling 3-18...success.
Autofilling 3-19...success.
Autofilling 3-20...success.
Autofilling 3-21...success.
Autofilling 3-22...success.
Autofilling 3-23...success.
Autofilling 3-24...success.
Autofilling 3-25...success.
Autofilling 3-26...success.
Autofilling 3-27...success.
Autofilling 3-28...success.
Autofilling 3-29 (first way)...success.
Autofilling 3-29 (second way)...success.
The two ways of autofilling 3-29 agree.
Recording autofilled block MergeState('single-binary', tip1='upstream/master', tip2='single-binary', goal='rebase')[0:4,0:30].
Traceback (most recent call last):
File "/home2/julian.stecklina/local/bin/git-imerge", line 3321, in <module>
main(sys.argv[1:])
File "/home2/julian.stecklina/local/bin/git-imerge", line 136, in wrapper
return f(*args, **kw)
File "/home2/julian.stecklina/local/bin/git-imerge", line 3199, in main
merge_state.auto_complete_frontier()
File "/home2/julian.stecklina/local/bin/git-imerge", line 2257, in auto_complete_frontier
frontier.auto_expand()
File "/home2/julian.stecklina/local/bin/git-imerge", line 1412, in auto_expand
if block.auto_expand_frontier():
File "/home2/julian.stecklina/local/bin/git-imerge", line 1710, in auto_expand_frontier
return self.auto_outline_frontier()
File "/home2/julian.stecklina/local/bin/git-imerge", line 1694, in auto_outline_frontier
return self.auto_outline_frontier(merge_frontier)
File "/home2/julian.stecklina/local/bin/git-imerge", line 1694, in auto_outline_frontier
return self.auto_outline_frontier(merge_frontier)
File "/home2/julian.stecklina/local/bin/git-imerge", line 1696, in auto_outline_frontier
f1, f2 = merge_frontier.partition(best_block)
File "/home2/julian.stecklina/local/bin/git-imerge", line 1342, in partition
'MergeFrontier partitioned with inappropriate block'
ValueError: MergeFrontier partitioned with inappropriate block
I started git imerge finish
(in an imerge started with git imerge merge foo
), then remembered that my user.name
and user.email
weren’t correctly set, so I cleared the commit message and exited the editor, expecting that this would abort the finish
, I could run git config
, and then re-run git imerge finish
. Instead, this happened:
Warning: you are leaving 1 commit behind, not connected to
any of your branches:abcdef imerge 'imerge-name': automatic merge 13-21
If you want to keep them by creating a new branch, this may be a good time
to do so with:git branch new_branch_name abcdef
Switched to branch 'starting-branch'
Aborting commit due to empty commit message.
Traceback (most recent call last):
File "$HOME/bin/git-imerge", line 3260, in
main(sys.argv[1:])
File "$HOME/bin/git-imerge", line 136, in wrapper
return f(_args, *_kw)
File "$HOME/bin/git-imerge", line 3208, in main
merge_state.simplify(refname, force=options.force)
File "$HOME/bin/git-imerge", line 2421, in simplify
self.simplify_to_merge(refname, force=force)
File "$HOME/bin/git-imerge", line 2407, in simplify_to_merge
check_call(['git', 'commit', '--amend'])
File "/usr/lib/python2.7/subprocess.py", line 540, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '[u'git', u'commit', u'--amend']' returned non-zero exit status 1
The imerge seems to have finished with the default commit message in the merge commit.
Some are probably obvious but it would be good to have them. Also I can't find how to run a test script after a tiny merge. Thanks.
When merging branch1 into branch2, with no new commits on branch2, or when branch2 has already been merged into branch1 the error is:
"There are no commits on 'branch2' that are not already in 'branch1'"
and the exit code is 1.
I suggest that git-imerge should reproduce the behavior of git merge and return 0. git-imerge has successfully determined there was nothing to do.
If you agree I can make the change and submit a pull request.
The bash completion script for git-imerge
includes comments that indicate it aims for compatibility with older bashes.
I tried the completion script on the bash supplied with Mac OS X (bash 3.2). It does work, but it also shows a warning message on each completion:
bash: words: bad array subscript
It seems the error comes from the expression "${words[i-1]}"
in the main completion function.
On the first loop, i
is 0 and so the expression evaluates to ${words[0-1]}
, which is equivalent to ${words[-1]}
, which was apparently invalid until bash 4.2 started allowing negative array subscripts to mean counting from the end (reference).
I don't think this code means to count from the end, though. I think that might be an accident that happens to have no obvious symptom in bash 4.2.
If I'm reading the code correctly, this is simply trying to find the word immediately preceded by "imerge" (eg "start" in "git imerge start"). We can sidestep the problem by starting the search at position 1 -- assuming that "imerge" will always be in at least the 0th position (in practice, "imerge" will almost certainly be position 1 or greater).
Once this is fixed, there's another complication that shows up.
Users can activate completion from any point in the command, although the very end is certainly the most common.
$ git imerge start master
If you type a whole command like the one above, move the cursor back to the space after the command, then hit the completion key, bash 3.2 aborts the entire command line with the message:
bash: $index: substring expression < 0
(bash 4.3 doesn't throw an error, but doesn't show any completions either)
I'm still investigating this one, but it's not obvious where the error is coming from.
Hi there - I have my git hooks set up to run ctags in the background on post-commit, post-checkout, and post-merge. git-imerge causes my computer to grind to a halt as 30 different ctag processes are kicked off.
Any thoughts on a better way of handling this sort of behaviour? git doesn't give a builtin way of suppressing hooks, right? Is there any precedent for setting an environment variable along the lines of RUNNING_AUTOMATED_CHECKOUTS=1
that hook scripts should look for?
With the rising popularity of git imerge, and the new fixes provided by newer versions in the repo, the need to have a version number (even if it is date based) becomes more needed.
git imerge --version
should provide a version information so that users can know if they have an up to date version or not.
Given a merge state like this:
0123456
0*******
1*.?.--+
2*.?|#??
3*.?|???
4*.?|???
5*.?|???
6*--+???
When the conflict at 4-2 has been resolved, git-imerge works downwards to the next conflict in column 4:
0123456
0*******
1*.?..-+
2*.?.*??
3*.?.|??
4*.?.+??
5*.?|???
6*--+???
At this point, I would expect git-imerge to check 6-4 (which in my test scenario will succeed), possibly having checked 6-2 to make sure that there are no more conflicts in that row.
However, the actual behaviour is to treat column 5 as the new left-most column and begin bisecting it. This feels wasteful since there is a good chance that column 5 has been unblocked to the same degree as column 4 by resolving the conflict at 4-2. Once git-imerge has discovered that 5-4 is mergeable, it does quickly test 6-4 and then autofill column 6.
Is it sensible to optimistically try the corner merges in this case before falling back to bisecting the column?
[I'm find this particularly painful because I've hacked my git-imerge to run make
on each non-autofill merge (see issue #58); it's been really useful for narrowing down incompatible changes, but is good at showing up these minor inefficiencies 😄]
We use gitflow for our branch management, which uses "feature/xxx" as default prefix for feature branches, so when I do an imerge it'd be handy to reuse that pattern directly without having to later do a git branch -m
, but imerge current doesn't let you.
After using rebase-with-history for some time ( and loving it ) and I'm wondering if it would be possible to support some form squash/reorder rebase along with keeping history?
I'd hate to see what sort of visualization the likes of gitk might make of something like that, even if it were possible.
I'm dealing with a reasonably large merge and in several places files have been moved in conflicting ways on both sides of the merge.
If I was doing this by hand my usual approach is to do a test merge, see what the rename conflicts are. Abort the merge, then manually move files around to make the move smoother. Commit that changes then do the merge again. If I get it right there are generally a pretty small number of conflicts at this point so fix them, and then before committing move the files on to where ever they really should have been on the target branch.
However, this now means that the merge is two commits and not one.
If I try and do this in the middle of an imerge I get the error:
Commit X is not usable; its parents are not known merge commits.
How would you recommend I get around this problem, is there some better way to do this?
I tried out imerge for porting a patch set across a couple of Linux versions. For one conflict I created a .config file in the root of the repo to build a Linux kernel. I resolved the conflict and did imerge continue. A bit later it came across another commit that tried to add a .config file, which obviously conflicted with the (uncommitted) .config I created during conflict resolution.
Now I am stuck at a pseudo conflict that I cannot resolve, because there is nothing to resolve. imerge continue gives me:
Commit e07733c1d8217c31bd663821aeffa42a880a2a2b is not usable; it is not a pairwise merge of adjacent parents
Is there a way to recover from this?
$ ../git-imerge/git-imerge merge upstream_version_1_0_0
Attempting automerge of 1-1...success.
Attempting automerge of 1-40...failure.
Attempting automerge of 1-21...failure.
Attempting automerge of 1-11...failure.
Attempting automerge of 1-6...success.
Attempting automerge of 1-9...success.
Attempting automerge of 1-10...failure.
Attempting automerge of 26-9...success.
Autofilling 1-9...success.
Autofilling 2-9...success.
Autofilling 3-9...success.
Autofilling 4-9...success.
Autofilling 5-9...success.
Autofilling 6-9...success.
Autofilling 7-9...success.
Autofilling 8-9...success.
Autofilling 9-9...success.
Autofilling 10-9...success.
Autofilling 11-9...success.
Autofilling 12-9...success.
Autofilling 13-9...success.
Autofilling 14-9...success.
Autofilling 15-9...success.
Autofilling 16-9...success.
Autofilling 17-9...success.
Autofilling 18-9...success.
Autofilling 19-9...success.
Autofilling 20-9...success.
Autofilling 21-9...success.
Autofilling 22-9...success.
Autofilling 23-9...success.
Autofilling 24-9...success.
Autofilling 25-9...success.
Autofilling 26-1...success.
Autofilling 26-2...success.
Autofilling 26-3...success.
Autofilling 26-4...success.
Autofilling 26-5...success.
Autofilling 26-6...success.
Autofilling 26-7...success.
Autofilling 26-8...success.
Autofilling 26-9 (first way)...success.
Autofilling 26-9 (second way)...success.
The two ways of autofilling 26-9 agree.
Traceback (most recent call last):
File "../git-imerge/git-imerge", line 3318, in
main(sys.argv[1:])
File "../git-imerge/git-imerge", line 136, in wrapper
return f(_args, *_kw)
File "../git-imerge/git-imerge", line 3134, in main
merge_state.auto_complete_frontier()
File "../git-imerge/git-imerge", line 2171, in auto_complete_frontier
frontier.auto_expand()
File "../git-imerge/git-imerge", line 1326, in auto_expand
if block.auto_expand_frontier():
File "../git-imerge/git-imerge", line 1624, in auto_expand_frontier
return self.auto_outline_frontier()
File "../git-imerge/git-imerge", line 1603, in auto_outline_frontier
best_block.auto_outline()
File "../git-imerge/git-imerge", line 1542, in auto_outline
merges.append((i1, i2, reparent(vertex_v1, [above, left])))
File "../git-imerge/git-imerge", line 511, in reparent
old_commit = check_output(['git', 'cat-file', 'commit', commit])
File "../git-imerge/git-imerge", line 94, in check_output
output = communicate(process)[0]
File "../git-imerge/git-imerge", line 240, in communicate
output = None if output is None else output.decode(PREFERRED_ENCODING)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 150: ordinal not in range(128)
What would lead to git-imerge
stopping and saying two commits have conflicts, but the one file marked as being modified by both branches has no actual conflict markers in it?
I really like what you've done with git-imerge; I used it successfully on Friday and am planning on doing most non-trivial merges and rebases with it from now on.
Mostly I was wondering how willing you would be to switch to perl. I know it's a slim chance, but if it were in perl users of msys git (about half, where I work) would be able to easily use this. I would gladly help, to the point of writing the initial conversion, but of course if you are not interested or willing to keep working on that afterwards it would be worthless.
In https://github.com/jyasskin/chromium, I'm trying to rebase-with-history service-worker-apps
(e49557a06ee349daee3edbac71b565ff315509cd) onto lkgr^
(ac5e723c9b830fecd3d13c65b66b0e0fd36e51f9). This gave the following output:
$ git imerge start --first-parent --goal=rebase-with-history --name service-worker-apps lkgr^
Attempting automerge of 1-1...success.
Attempting automerge of 1-1789...success.
Attempting automerge of 1-2683...failure.
Attempting automerge of 1-2236...failure.
Attempting automerge of 1-2013...failure.
Attempting automerge of 1-1901...success.
Attempting automerge of 1-1957...failure.
Attempting automerge of 1-1929...success.
Attempting automerge of 1-1943...success.
Attempting automerge of 1-1950...failure.
Attempting automerge of 1-1947...success.
Attempting automerge of 1-1949...failure.
Attempting automerge of 1-1948...success.
Autofilling 1-1...success.
Autofilling 1-2...success.
...
Each of the Autofilling
lines takes about a second to display, so this rebase is going to take about an hour, which is too long to do interactively. Is this an intrinsic part of the imerge process, or is it optimizable?
I got the following output when attempting to use imerge to merge in https://github.com/odigeoteam/nui/tree/master from https://github.com/Stunner/nui/tree/all-changes.
$ git-imerge merge odigeoteam/master
Attempting automerge of 1-1...success.
Attempting automerge of 1-11...success.
Attempting automerge of 1-17...success.
Attempting automerge of 1-20...success.
Attempting automerge of 1-21...success.
Attempting automerge of 4-21...failure.
Attempting automerge of 3-21...failure.
Attempting automerge of 2-21...failure.
Attempting automerge of 2-1...success.
Attempting automerge of 2-11...failure.
Attempting automerge of 2-6...failure.
Attempting automerge of 2-4...success.
Attempting automerge of 2-5...Traceback (most recent call last):
File "/usr/local/bin/git-imerge", line 3316, in <module>
main(sys.argv[1:])
File "/usr/local/bin/git-imerge", line 136, in wrapper
return f(*args, **kw)
File "/usr/local/bin/git-imerge", line 3132, in main
merge_state.auto_complete_frontier()
File "/usr/local/bin/git-imerge", line 2169, in auto_complete_frontier
frontier.auto_expand()
File "/usr/local/bin/git-imerge", line 1324, in auto_expand
if block.auto_expand_frontier():
File "/usr/local/bin/git-imerge", line 1622, in auto_expand_frontier
return self.auto_outline_frontier()
File "/usr/local/bin/git-imerge", line 1592, in auto_outline_frontier
merge_frontier = MergeFrontier.compute_by_bisection(self)
File "/usr/local/bin/git-imerge", line 972, in compute_by_bisection
2, i2 - 1,
File "/usr/local/bin/git-imerge", line 212, in find_first_false
if f(mid):
File "/usr/local/bin/git-imerge", line 971, in <lambda>
lambda i: block.is_mergeable(i1, i),
File "/usr/local/bin/git-imerge", line 1475, in is_mergeable
automerge(self[i1, 0].sha1, self[0, i2].sha1)
File "/usr/local/bin/git-imerge", line 563, in automerge
call_silently(['git', 'checkout', '-f', commit1])
File "/usr/local/bin/git-imerge", line 230, in call_silently
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '[u'git', u'checkout', u'-f', u'fc97a0495f68b2d6d5082f9bf26ac83ab7688a61']' returned non-zero exit status 128
I was wondering if git-imerge could be used for a scenario where:
This would allow me to start resolving conflicts now when either of the changes are fresh in my mind and I know how to solve the conflicts.
Thanks
I'm not sure whether it's possible to add support for this, but it'd be nice to be able to choose a merge strategy and custom strategy options (or if that's not possible, the options for whichever merge strategy git-imerge
is using).
Use case: use the ignore-space-change
and related options of the recursive
strategy.
At the moment, all it would have to do is rewrite the shebang line at the top of git-imerge to cause it to be run with the correct Python interpreter for the target system. Soon we probably want to move part of git-imerge to a library to make testing easier, and that will require a bit more structure in the project.
Something like setuptools is probably the way to go.
I'm looking at my .git/config a few days after using git imerge serveral times and sometimes also resetting git-imerge runs. Now my .git/config contains several empty [imerge]
sections.
It seems git imerge puts some state information there but doesn't always clean up properly? Is .git/config really the best place for state info?
If the bisection heuristic fails, it can be that an autofill merge fails even though it was expected to succeed. We need a way to test such scenarios systematically. I think the easiest way would be to use an object that can mock a repository (maybe MergeState can be mocked?) and simulate arbitrary successes and failures.
Issue #3 is an example of a problem handling unexpected failures.
For example, when running test-unconflicted, this kind of warning appears multiple times. Suppress it when we're sure what we're doing.
There's a short lived tradition at work to push the oldest commit to master. Happily I jumped on my 1.5 year old refactor branch and modernized it through git-imerge. Imagine my disappointment after 3 days of work that all dates have been clobbered and set to the exact time when I did git-imerge finish :( My coworker pointed at me and laughed.
Figured out why it happens, all calls to git commit-tree disregards vital information from original commit. They should be called with
GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE
GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE
set from original commit. (thankfully my git-imerge work has so far only been done on branches where I was the sole author/committer)
Don't know if you were aware of this, but python2 isn't available on OS X, so I had to create a symlink before I could run imerge. On 10.8, the python
binary is 2.7.2.
I've not got much experience with python... I assume python2 is there for a good reason?
I solved the problem by passing --no-color
to git-imerge diagram
but I thought I'd let you know.
I'm using Git Bash in Windows 7 (python 2.7.5 installed). When running git-imerge diagram
I get a garbage output like this:
$ git-imerge diagram
←[1;32m*←[0m←[1;32m*←[0m
←[1;32m*←[0m←[1;31m#←[0m
←[1;32m*←[0m←[1;31m?←[0m
←[1;32m*←[0m←[1;31m?←[0m
←[1;32m*←[0m←[1;31m?←[0m
←[1;32m*←[0m←[1;31m?←[0m
Normally it's like this:
$ git-imerge diagram --no-color
**
*#
*?
*?
*?
*?
*?
*?
*?
Not sure what's the issue here (though I haven't investigated). I do use various NodeJS apps that are doing the coloring and they're working fine for me.
I'm trying to use 'git-imerge' to merge one repository into another and receive a message that there is no unique merge base. I decided to modify the code so that it would use the first merge base that is found. After that I was able to merge the repositories successfully.
Is there a reason that this might be a bad idea? Is there a better way to handle cases where there are multiple merge bases?
I just completed the final manual merge of an 18/6 imerge and now I find I can't finish it. The result I get is
% git-imerge finish
fatal: invalid date format: 2013-07-24
Traceback (most recent call last):
File "/usr/bin/git-imerge", line 2795, in <module>
main(sys.argv[1:])
File "/usr/bin/git-imerge", line 222, in wrapper
return f(*args, **kw)
File "/usr/bin/git-imerge", line 2743, in main
merge_state.simplify(refname, force=options.force)
File "/usr/bin/git-imerge", line 2209, in simplify
self.simplify_to_rebase(refname, force=force)
File "/usr/bin/git-imerge", line 2176, in simplify_to_rebase
tree, [commit], msg=get_log_message(orig), metadata=authordata,
File "/usr/bin/git-imerge", line 472, in commit_tree
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['git', 'commit-tree', '0df2c0115fddd350eee35765283df964eecc7489', '-p', 'bcb4b458973531aa5cb318c600f0431e9aa2f509']' returned non-zero exit status 128
I started this imerge on master
with
git-imerge start --name=foobar --goal=rebase --first-parent devo
I had a look at the code raising the exception but can't really work out what causes this. I also printed out the message (msg
) and then ran the git commit-tree
command manually, with the arguments above and passing the copied message on stdin
, that worked just fine.
Any suggestions on how to finish off the imerge in this case?
While git-imerge is great for identifying where textual conflicts are introduced, I would also like to be able to detect where logical conflicts are introduced.
At the moment this can be accomplished using the --manual
mode and wrapping a script around make && git imerge continue
, but it would be nice if git-imerge could be automated in the same way as git-bisect in order to check the consistency of the result even when no textual conflict has been found.
When there is a merge conflict that must be resolved a very helpful message gets output. Then I start looking at the two commits, trying to understand what they were trying to do, before going to the mergetool to solve them.
The problem is that if I want to go back to see, for instance, the other commit, I need to scroll up the terminal buffer to find that original helpful message. It would be nice if there were a "status" operation of imerge that can output that again.
Thanks
@mhagger thanks for pulling in the makefile change. I still need a release tag on the current version to be able to create a homebrew recipe for it.
Thanks a bunch!
I'm getting the following error when I tried to use imerge to resolve a merge conflict. I've pushed the two branches (imerge-master and imerge-branch) to my buildbot fork (https://github.com/jaredgrubb/buildbot.git)
$ git checkout imerge-master
$ git imerge start --goal rebase --name slaveinfo --first-parent imerge-branch
[ ... lots of stuff ... ]
Autofilling 4-5 (first way)...success.
Autofilling 4-5 (second way)...success.
The two ways of autofilling 4-5 agree.
Recording autofilled block MergeState('slaveinfo', goal='rebase')[0:5,1:6].
Attempting automerge of 5-2...failure.
error: unable to create directory for .git/logs/refs/heads/imerge/slaveinfo
fatal: Cannot update the ref 'refs/heads/imerge/slaveinfo'.
Traceback (most recent call last):
File "/Users/jaredgrubb/bin/git-imerge", line 2796, in <module>
main(sys.argv[1:])
File "/Users/jaredgrubb/bin/git-imerge", line 222, in wrapper
return f(*args, **kw)
File "/Users/jaredgrubb/bin/git-imerge", line 2673, in main
request_user_merge(merge_state, e.i1, e.i2)
File "/Users/jaredgrubb/bin/git-imerge", line 2269, in request_user_merge
refname, above.sha1,
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 542, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['git', 'update-ref', '-m', "imerge 'slaveinfo': Prepare merge 5-2", 'refs/heads/imerge/slaveinfo', '5dea1f793b2eb0fd2b01c662f0d5a93594ed3e4e']' returned non-zero exit status 128
I get following trace...:
git-imerge continue 0
[imerge/feature/coresplit 74fb99b] imerge 'feature/coresplit': manual merge 6-1
Merge has been recorded for merge 6-1.
Attempting automerge of 6-2...success.
Attempting automerge of 6-4...success.
Autofilling 6-2...success.
Autofilling 6-3...success.
Autofilling 6-4...success.
Recording autofilled block MergeState('feature/coresplit', tip1='tmp', tip2='feature/coresplit', goal='merge')[5:7,1:5].
Attempting automerge of 7-1...Traceback (most recent call last):
File "/home/users/myuser/bin/git-imerge", line 3260, in
main(sys.argv[1:])
File "/home/users/myuser/bin/git-imerge", line 136, in wrapper
return f(_args, *_kw)
File "/home/users/myuser/bin/git-imerge", line 3157, in main
merge_state.auto_complete_frontier()
File "/home/users/myuser/bin/git-imerge", line 2198, in auto_complete_frontier
frontier.auto_expand()
File "/home/users/myuser/bin/git-imerge", line 1353, in auto_expand
if block.auto_expand_frontier():
File "/home/users/myuser/bin/git-imerge", line 1651, in auto_expand_frontier
return self.auto_outline_frontier()
File "/home/users/myuser/bin/git-imerge", line 1621, in auto_outline_frontier
merge_frontier = MergeFrontier.compute_by_bisection(self)
File "/home/users/myuser/bin/git-imerge", line 910, in compute_by_bisection
if not block.is_mergeable(1, 1):
File "/home/users/myuser/bin/git-imerge", line 1504, in is_mergeable
automerge(self[i1, 0].sha1, self[0, i2].sha1)
File "/home/users/myuser/bin/git-imerge", line 600, in automerge
call_silently(['git', 'reset', '--merge'])
File "/home/users/myuser/bin/git-imerge", line 230, in call_silently
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '[u'git', u'reset', u'--merge']' returned non-zero exit status 128
When using an existing file in a manual merge due to incorporate_user_merge using diff-index and there being no changes required for the existing file, the git commit does not occur within the exception, so the commit remains the same and the incorrect heads are found within incorporate_manual_merge
git-imerge start --name=rb29 --goal=merge --first-parent node
Attempting automerge of 1-1...success.
Attempting automerge of 1-8...success.
Attempting automerge of 1-12...success.
Attempting automerge of 1-14...success.
Attempting automerge of 2939-14...Traceback (most recent call last):
File "/home/roger/git-imerge/git-imerge", line 2796, in <module>
main(sys.argv[1:])
File "/home/roger/git-imerge/git-imerge", line 222, in wrapper
return f(*args, **kw)
File "/home/roger/git-imerge/git-imerge", line 2671, in main
merge_state.auto_complete_frontier()
File "/home/roger/git-imerge/git-imerge", line 2028, in auto_complete_frontier
frontier.auto_expand()
File "/home/roger/git-imerge/git-imerge", line 1263, in auto_expand
if block.auto_outline_frontier():
File "/home/roger/git-imerge/git-imerge", line 1488, in auto_outline_frontier
merge_frontier = MergeFrontier.compute_by_bisection(self)
File "/home/roger/git-imerge/git-imerge", line 944, in compute_by_bisection
if block.is_mergeable(block.len1 - 1, i2 - 1):
File "/home/roger/git-imerge/git-imerge", line 1406, in is_mergeable
automerge(self[i1, 0].sha1, self[0, i2].sha1)
File "/home/roger/git-imerge/git-imerge", line 575, in automerge
call_silently(['git', 'reset', '--merge'])
File "/home/roger/git-imerge/git-imerge", line 318, in call_silently
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['git', 'reset', '--merge']' returned non-zero exit status 128
A simple implementation (one that can do no conflict resolution of differing resolution conflicts) should be pretty easy.
This was first discussed in #72.
Suppose an imerge is in the following state:
o---0---1---2---3
| | |
A---o---X
| | |
B---Y---?
|
C
Normally you would fill in ?
by merging X
and Y
directly. But what if you realize that the change from 1
to 2
was actually too big, and it would be easier to resolve the merge in two steps? You might like to introduce a helper commit H
, maybe like:
o---0---1---2---3
| | |
A---o---X
| | |
B---Y-H-M
|
C
In this situation, it is quite possible the "helper" step would be useful for later merges. For example, when it comes time, in the next row, to fill in this ?
:
o---0---1---2---3
| | |
A---o---X
| | |
B---Y-H-M
| | |
C---T---?
it might actually be easier to first compute the merge of H
and T
, and then compute the merge of M
and U
:
o---0---1---2---3
| | |
A---o---X
| | |
B---Y-H-M
| | | |
C---T-U-V
It would be nice if git-imerge
could handle non-rectangular merge topologies like this, even if they arise while a merge is already in progress.
The simplification might be tricky in the general case. If the goal was a rebase, then it might be that the end result should be
o---0---A---B---C---T---U---V
It is not obvious where the commit messages for U
and V
should be taken from. Probably they should come from commits H
and U
, respectively, but it might be hard to get the user to type good and appropriate messages for these commits.
On the other hand, it might be that commits H
and U
were added only to help Git, and do not belong in the final history (for example, they might not even build). In that case, the final rebase result should be
o---0---A---B---C---T---V
and it is clear where the commit messages should come from.
It would be quite a lot of work to build this feature into git imerge
, because a lot of the code assumes a "rectangular grid" topology of commits and merges.
Hey, thanks for this awesome project!
I'm having an issue when rebasing with imerge
; here's how I start it:
git imerge start --name=result --goal=rebase --first-parent master
and when I git imerge finish
I get this:
Traceback (most recent call last):
File "/usr/bin/git-imerge", line 3318, in <module>
main(sys.argv[1:])
File "/usr/bin/git-imerge", line 136, in wrapper
return f(*args, **kw)
File "/usr/bin/git-imerge", line 3266, in main
merge_state.simplify(refname, force=options.force)
File "/usr/bin/git-imerge", line 2392, in simplify
self.simplify_to_rebase(refname, force=force)
File "/usr/bin/git-imerge", line 2351, in simplify_to_rebase
authordata = get_author_info(orig)
File "/usr/bin/git-imerge", line 377, in get_author_info
str('GIT_AUTHOR_NAME'): str(a[0]),
UnicodeEncodeError: 'ascii' codec can't encode character u'\xc1' in position 0: ordinal not in range(128)
Not sure how to provide more info to help with the diagnostics.
Since git-imerge can track which merges were made automatically and which manually due to conflicts, and because manual merges can themselves be done incorrectly by the user, it could be useful to add a new simplification strategy (haven't found a good name) that will do the following transformation:
From a imerge complete diagram like this:
*******
*.m....
*......
Where:
* - original commits on the two branches
. - automatic merge
m - manual merge
The resulting commits will be:
*******
* m .
* . .
The convention being that the unrepresented commits are not stored at all, and only the represented ones are finally kept. The parents of each of the kept merges are the closest kept commits to the left, and, respectively, up.
This way the problematic commits are highlighted in the history and can be reviewed individually later or tested.
I am getting this message when trying to merge two branches:
kevins-mbp:TAMenuApp kevin$ git-imerge merge dev_build
u'v3_merge' and 'dev_build' do not have a unique merge base
but when I check the base of the two branches with git I get this:
kevins-mbp:TAMenuApp kevin$ git merge-base dev_build v3_merge
0c16efd68f4defa7bd39f092a631691ace269a9d
which is correct. In fact, I can perform a regular git merge just fine, it just results in an insane amount of conflicts so I'd rather use imerge. Can you think of a reason why git-imerge disagrees?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.