Re: Do not raise conflict when a code in a patch was already added

2018-08-21 Thread Igor Djordjevic
Hi Konstantin,

On 21/08/2018 11:37, Konstantin Kharlamov wrote:
> 
> > There's another possibility (and I think it is what happens 
> > actually in Konstantin's case): When one side added lines 1 2 and the 
> > other side added 1 2 3, then the actual conflict is 
> > << 1 2 == 1 2 3 >>, but our merge code is able to move the identical 
> > part out of the conflicted section: 1 2 << == 3 >>. But this is just 
> > a courtesy for the user; the real conflict is the original one. 
> > Without this optimization, the work to resolve the conflict would be 
> > slightly more arduous.
> 
> Yeah, thanks, that's what happens. And I'm wondering, is it really 
> needed to raise a conflict there? Would it be worth to just apply the 
> line "3", possibly with a warning or an interactive question to user 
> (apply/raise) that identical parts were ignored?

I see how this might make sense in the given example of "A added 1 
and 2, B added 1 and 2 and 3", but I'm afraid that might be a too 
narrow view.

What we actually don't know is if A deliberately chose not to include 
3, or even worse, if A started from having "1 and 2 and 3" in there, 
and then decided to remove 3.

In both these situation just applying 3 would be wrong, and raising a 
conflict seems as the most (and only?) sensible solution.

Applying _and_ asking for confirmation might be interesting, but I'm 
afraid it would favor specific use case only, being an annoyance in 
all the others (where it should really be a conflict, and you now 
have additional prompt to deal with).

That said, it would indeed be nice to have a way to communicate to 
`git rebase` that we are just splitting later commit into smaller 
parts preceding it, so situations like this could be resolved 
automatically and without conflicts, as you'd expected - but only 
within that narrow, user-provided/communicated context, not in 
general case.

Regards, Buga


Re: Do not raise conflict when a code in a patch was already added

2018-08-21 Thread Konstantin Kharlamov




On 20.08.2018 22:22, Johannes Sixt wrote:

Am 20.08.2018 um 19:40 schrieb Phillip Wood:

On 20/08/2018 11:22, Konstantin Kharlamov wrote:

It's spectacular, that content of one of inserted conflict markers is
empty, so all you have to do is to remove the markers, and use `git add`
on the file, and then `git rebase --continue`

Its a lot of unncessary actions, git could just figure that the code it
sees in the patch is already there, being a part of another commit.


If there are conflict markers where one side is empty it means that some
lines from the merge base (which for a rebase is the parent of the
commit being picked) have been deleted on one side and modified on the
other. Git cannot know if you want to use the deleted version or the
modified version.


There's another possibility (and I think it is what happens actually in 
Konstantin's case): When one side added lines 1 2 and the other side 
added 1 2 3, then the actual conflict is << 1 2 == 1 2 3 >>, but our 
merge code is able to move the identical part out of the conflicted 
section: 1 2 << == 3 >>. But this is just a courtesy for the user; the 
real conflict is the original one. Without this optimization, the work 
to resolve the conflict would be slightly more arduous.


Yeah, thanks, that's what happens. And I'm wondering, is it really 
needed to raise a conflict there? Would it be worth to just apply the 
line "3", possibly with a warning or an interactive question to user 
(apply/raise) that identical parts were ignored?


Re: Do not raise conflict when a code in a patch was already added

2018-08-20 Thread Johannes Sixt

Am 20.08.2018 um 19:40 schrieb Phillip Wood:

On 20/08/2018 11:22, Konstantin Kharlamov wrote:

It's spectacular, that content of one of inserted conflict markers is
empty, so all you have to do is to remove the markers, and use `git add`
on the file, and then `git rebase --continue`

Its a lot of unncessary actions, git could just figure that the code it
sees in the patch is already there, being a part of another commit.


If there are conflict markers where one side is empty it means that some
lines from the merge base (which for a rebase is the parent of the
commit being picked) have been deleted on one side and modified on the
other. Git cannot know if you want to use the deleted version or the
modified version.


There's another possibility (and I think it is what happens actually in 
Konstantin's case): When one side added lines 1 2 and the other side 
added 1 2 3, then the actual conflict is << 1 2 == 1 2 3 >>, but our 
merge code is able to move the identical part out of the conflicted 
section: 1 2 << == 3 >>. But this is just a courtesy for the user; the 
real conflict is the original one. Without this optimization, the work 
to resolve the conflict would be slightly more arduous.


-- Hannes


Re: Do not raise conflict when a code in a patch was already added

2018-08-20 Thread Phillip Wood
On 20/08/2018 11:22, Konstantin Kharlamov wrote:
> So, steps-to-reproduce below rather full of trivia like setting up a
> repo, but the TL;DR is:
> 
> Upon using `git rebase -i HEAD~1` and then `git add -p` to add part of a
> "hunk" as one commit, and then using `git rebase --continue` so the
> other part of hunk would be left in top commit; git raises a conflict.

I think this is a misleading error message as in your example below
there are no conflicts, just unstaged changes. git-rebase.sh has the
following code


git update-index --ignore-submodules --refresh &&
git diff-files --quiet --ignore-submodules || {
echo "$(gettext "You must edit all merge conflicts and then
mark them as resolved using git add")"
exit 1

I think this pre-dates interactive rebases when the only unstaged
changes could be conflicts.

> 
> It's spectacular, that content of one of inserted conflict markers is
> empty, so all you have to do is to remove the markers, and use `git add`
> on the file, and then `git rebase --continue`
> 
> Its a lot of unncessary actions, git could just figure that the code it
> sees in the patch is already there, being a part of another commit.

If there are conflict markers where one side is empty it means that some
lines from the merge base (which for a rebase is the parent of the
commit being picked) have been deleted on one side and modified on the
other. Git cannot know if you want to use the deleted version or the
modified version. You can use 'git diff --cc' to see the combined diff
which should show the lines being deleted on both sides and an addition
on the side with the modified lines. You can also set the
merge.conflictStyle config variable to diff3 to see the original text as
well as the text from the merge heads.

Best Wishes

Phillip

> 
> Maybe git could issue a warning, or to question a user interactively
> (y/n); but raising a conflict IMO is unnecessary.
> 
> # Steps to reproduce
> 
> In empty dir execute:
> 
> $ git init
> $ touch test
> Initialized empty Git repository in /tmp/test/.git/
> $ git add test
> $ git commit
> [master (root-commit) a7ce543] 1st commit
>  1 file changed, 2 insertions(+)
>  create mode 100644 test
> $ echo -e "foo\nbar" > test # content you'll want to break
> $ git add -u && git commit
> [detached HEAD 9e28331] 2-nd commit
>  1 file changed, 2 insertions(+)
> $ git rebase -i --root
> Stopped at a7ce543...  1st commit
> You can amend the commit now, with
> 
>   git commit --amend
> 
> Once you are satisfied with your changes, run
> 
>   git rebase --continue
> 
> Put "edit" for the 2-nd commit
> 
> $ git reset HEAD^
> Unstaged changes after reset:
> M   test
> $ git add -p
> diff --git a/test b/test
> index e69de29..3bd1f0e 100644
> --- a/test
> +++ b/test
> @@ -0,0 +1,2 @@
> +foo
> +bar
> Stage this hunk [y,n,q,a,d,e,?]? e
> 
> ╭─constantine@constantine-N61Ja  /tmp/test ‹node-›  ‹› (e721fa3*)
> ╰─$ git commit
> [detached HEAD 27b2f63] add foo
>  1 file changed, 1 insertion(+)
> ╭─constantine@constantine-N61Ja  /tmp/test ‹node-›  ‹› (27b2f63*)
> ╰─$ git rebase --continue
> test: needs update
> You must edit all merge conflicts and then
> mark them as resolved using git add
> 
> What happened is that it's obvious that the hunk was broken to multiple
> commits, and git should figure that out, and not to raise a conflict.
> 
> Side note: for some reason in the test git didn't insert conflict
> markers. It did in real-world usecase though, and there was simply no
> content inside one of them.
> 



Do not raise conflict when a code in a patch was already added

2018-08-20 Thread Konstantin Kharlamov

So, steps-to-reproduce below rather full of trivia like setting up a
repo, but the TL;DR is:

Upon using `git rebase -i HEAD~1` and then `git add -p` to add part of a
"hunk" as one commit, and then using `git rebase --continue` so the
other part of hunk would be left in top commit; git raises a conflict.

It's spectacular, that content of one of inserted conflict markers is
empty, so all you have to do is to remove the markers, and use `git add`
on the file, and then `git rebase --continue`

Its a lot of unncessary actions, git could just figure that the code it
sees in the patch is already there, being a part of another commit.

Maybe git could issue a warning, or to question a user interactively 
(y/n); but raising a conflict IMO is unnecessary.


# Steps to reproduce

In empty dir execute:

$ git init
$ touch test
Initialized empty Git repository in /tmp/test/.git/
$ git add test
$ git commit
[master (root-commit) a7ce543] 1st commit
 1 file changed, 2 insertions(+)
 create mode 100644 test
$ echo -e "foo\nbar" > test # content you'll want to break
$ git add -u && git commit
[detached HEAD 9e28331] 2-nd commit
 1 file changed, 2 insertions(+)
$ git rebase -i --root
Stopped at a7ce543...  1st commit
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue

Put "edit" for the 2-nd commit

$ git reset HEAD^
Unstaged changes after reset:
M   test
$ git add -p
diff --git a/test b/test
index e69de29..3bd1f0e 100644
--- a/test
+++ b/test
@@ -0,0 +1,2 @@
+foo
+bar
Stage this hunk [y,n,q,a,d,e,?]? e

╭─constantine@constantine-N61Ja  /tmp/test ‹node-›  ‹› (e721fa3*)
╰─$ git commit
[detached HEAD 27b2f63] add foo
 1 file changed, 1 insertion(+)
╭─constantine@constantine-N61Ja  /tmp/test ‹node-›  ‹› (27b2f63*)
╰─$ git rebase --continue
test: needs update
You must edit all merge conflicts and then
mark them as resolved using git add

What happened is that it's obvious that the hunk was broken to multiple
commits, and git should figure that out, and not to raise a conflict.

Side note: for some reason in the test git didn't insert conflict
markers. It did in real-world usecase though, and there was simply no
content inside one of them.