All of lore.kernel.org
 help / color / mirror / Atom feed
* Request for adding a simple mechanism to exclude files from Git merge operation
@ 2020-06-20 18:21 Tiran Meltser
  2020-06-21 15:43 ` Philip Oakley
  2020-06-22 19:41 ` brian m. carlson
  0 siblings, 2 replies; 16+ messages in thread
From: Tiran Meltser @ 2020-06-20 18:21 UTC (permalink / raw)
  To: git; +Cc: Amir Yosef

Hi,
This topic is quite common in various use cases (e.g. production configuration vs. staging one) and there are quite a few talks about it in the web.
Nevertheless, there is no specific solution to this problem, only partial workarounds (including the famous merge driver “ours”).

I would like to suggest adding the git a simple and precise handling for the need to mark file(s)/folder(s) that are branch specific and should not be involved in merge operation at all.

2 suggestions I can think of are (but any good solution would suffice):
• Adding additional merge strategy indication the file/folder is excluded from merges (e.g. merge=disabled/none/skip/…)
• Adding a new configuration file (like .gitignore) for tracking these special files/folders, for example: .gitisolate/.gitquarantine/.gitbranchspecific/.gitsilo/…

Any comment would be appreciated.

10x,
Tiran Meltser
________________________________
This e-mail message may contain confidential or proprietary information of Mavenir Systems, Inc. or its affiliates and is intended solely for the use of the intended recipient(s). If you are not the intended recipient of this message, you are hereby notified that any review, use or distribution of this information is absolutely prohibited and we request that you delete all copies in your control and contact us by e-mailing to security@mavenir.com. This message contains the views of its author and may not necessarily reflect the views of Mavenir Systems, Inc. or its affiliates, who employ systems to monitor email messages, but make no representation that such messages are authorized, secure, uncompromised, or free from computer viruses, malware, or other defects. Thank You

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-20 18:21 Request for adding a simple mechanism to exclude files from Git merge operation Tiran Meltser
@ 2020-06-21 15:43 ` Philip Oakley
  2020-06-22 18:42   ` [E] " Tiran Meltser
  2020-06-22 19:41 ` brian m. carlson
  1 sibling, 1 reply; 16+ messages in thread
From: Philip Oakley @ 2020-06-21 15:43 UTC (permalink / raw)
  To: Tiran Meltser, git; +Cc: Amir Yosef

On 20/06/2020 19:21, Tiran Meltser wrote:
> Hi,
> This topic is quite common in various use cases (e.g. production configuration vs. staging one) and there are quite a few talks about it in the web.
> Nevertheless, there is no specific solution to this problem, only partial workarounds (including the famous merge driver “ours”).
>
> I would like to suggest adding the git a simple and precise handling for the need to mark file(s)/folder(s) that are branch specific and should not be involved in merge operation at all.
>
> 2 suggestions I can think of are (but any good solution would suffice):
> • Adding additional merge strategy indication the file/folder is excluded from merges (e.g. merge=disabled/none/skip/…)
> • Adding a new configuration file (like .gitignore) for tracking these special files/folders, for example: .gitisolate/.gitquarantine/.gitbranchspecific/.gitsilo/…
>
> Any comment would be appreciated.
>
>
There has been a lot of previous discussion on "precious" files in the
past, but without any solid solution.
(https://lore.kernel.org/git/?q=precious+file to start).


There is a current thread on progressive merge resolution, where not all
conflicts can be resolved by one person at one time, which may also be
of interest.
https://public-inbox.org/git/BY5PR19MB3400DC6B6065C1FFF2ED289890990@BY5PR19MB3400.namprd19.prod.outlook.com/T/#m56b34554612b44be17e61da6486c1f709c2cfe54

Philip

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [E] Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-21 15:43 ` Philip Oakley
@ 2020-06-22 18:42   ` Tiran Meltser
  0 siblings, 0 replies; 16+ messages in thread
From: Tiran Meltser @ 2020-06-22 18:42 UTC (permalink / raw)
  To: Philip Oakley, git; +Cc: Amir Yosef, Tiran Meltser

Hi Philip,
First - thanks for taking the time to comment on the issue.
Second - as for the "precious" file, not sure this is my case; it could go there, but as you indicated it has been around for some time without progressing anywhere.
Third - the last link you sent doesn't seem to be related to my issue as it deals with complex merges, while my request is very simple - give the ability to mark files/folders as omitted from a merge operation (branch specific files).

IMHO this feature isn't complicated and can bring lots of benefits to the table.

Hope someone will take up the glove...

Tiran.
-----Original Message-----
From: Philip Oakley <philipoakley@iee.email>
Sent: Sunday, June 21, 2020 6:43 PM
To: Tiran Meltser <Tiran.Meltser@mavenir.com>; git@vger.kernel.org
Cc: Amir Yosef <Amir.Yosef@mavenir.com>
Subject: [E] Re: Request for adding a simple mechanism to exclude files from Git merge operation

[EXTERNAL EMAIL] DO NOT CLICK links or attachments unless you recognize the sender and know the content is safe.

On 20/06/2020 19:21, Tiran Meltser wrote:
> Hi,
> This topic is quite common in various use cases (e.g. production configuration vs. staging one) and there are quite a few talks about it in the web.
> Nevertheless, there is no specific solution to this problem, only partial workarounds (including the famous merge driver “ours”).
>
> I would like to suggest adding the git a simple and precise handling for the need to mark file(s)/folder(s) that are branch specific and should not be involved in merge operation at all.
>
> 2 suggestions I can think of are (but any good solution would suffice):
> • Adding additional merge strategy indication the file/folder is
> excluded from merges (e.g. merge=disabled/none/skip/…) • Adding a new
> configuration file (like .gitignore) for tracking these special
> files/folders, for example:
> .gitisolate/.gitquarantine/.gitbranchspecific/.gitsilo/…
>
> Any comment would be appreciated.
>
>
There has been a lot of previous discussion on "precious" files in the past, but without any solid solution.
(https://lore.kernel.org/git/?q=precious+file to start).


There is a current thread on progressive merge resolution, where not all conflicts can be resolved by one person at one time, which may also be of interest.
https://public-inbox.org/git/BY5PR19MB3400DC6B6065C1FFF2ED289890990@BY5PR19MB3400.namprd19.prod.outlook.com/T/#m56b34554612b44be17e61da6486c1f709c2cfe54

Philip
________________________________
This e-mail message may contain confidential or proprietary information of Mavenir Systems, Inc. or its affiliates and is intended solely for the use of the intended recipient(s). If you are not the intended recipient of this message, you are hereby notified that any review, use or distribution of this information is absolutely prohibited and we request that you delete all copies in your control and contact us by e-mailing to security@mavenir.com. This message contains the views of its author and may not necessarily reflect the views of Mavenir Systems, Inc. or its affiliates, who employ systems to monitor email messages, but make no representation that such messages are authorized, secure, uncompromised, or free from computer viruses, malware, or other defects. Thank You

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-20 18:21 Request for adding a simple mechanism to exclude files from Git merge operation Tiran Meltser
  2020-06-21 15:43 ` Philip Oakley
@ 2020-06-22 19:41 ` brian m. carlson
  2020-06-23 12:44   ` Sergey Organov
  1 sibling, 1 reply; 16+ messages in thread
From: brian m. carlson @ 2020-06-22 19:41 UTC (permalink / raw)
  To: Tiran Meltser; +Cc: git, Amir Yosef

[-- Attachment #1: Type: text/plain, Size: 1644 bytes --]

On 2020-06-20 at 18:21:40, Tiran Meltser wrote:
> Hi,
> This topic is quite common in various use cases (e.g. production configuration vs. staging one) and there are quite a few talks about it in the web.
> Nevertheless, there is no specific solution to this problem, only partial workarounds (including the famous merge driver “ours”).

In general, this is a hard problem.  When you perform a merge, you're
asking to incorporate changes from both heads against a common merge
base.  What does it mean when you want to merge two branches together
but not make any changes?  Which version do you want, ours or theirs?
Normally merges are symmetric, so if you want non-symmetric behavior,
you have to define what it's supposed to be.

In addition, it's probably not the case that you want _never_ to modify
the contents of a file on a merge.  For example, if you have a feature
branch to update the production configuration to fix an issue or add a
new option, you probably do very much want that merge to succeed and not
be a no-op, so a configuration in .gitattributes may not be helpful for
your use case.

Because this is such a tricky problem and there usually isn't a
consistent set of behavior that people _always_ want to apply (unlike,
say, line endings), the general recommendation here is that folks just
avoid this problem altogether.  For example, your repository can contain
configs for development, production, and staging and a script can copy
the appropriate one into place based on an environment variable or
hostname.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-22 19:41 ` brian m. carlson
@ 2020-06-23 12:44   ` Sergey Organov
  2020-06-23 16:16     ` Philip Oakley
  2020-06-23 17:08     ` Elijah Newren
  0 siblings, 2 replies; 16+ messages in thread
From: Sergey Organov @ 2020-06-23 12:44 UTC (permalink / raw)
  To: brian m. carlson; +Cc: Tiran Meltser, git, Amir Yosef

"brian m. carlson" <sandals@crustytoothpaste.net> writes:

> On 2020-06-20 at 18:21:40, Tiran Meltser wrote:
>> Hi,
>> This topic is quite common in various use cases (e.g. production
>> configuration vs. staging one) and there are quite a few talks about
>> it in the web.
>> Nevertheless, there is no specific solution to this problem, only
>> partial workarounds (including the famous merge driver “ours”).
>
> In general, this is a hard problem.  When you perform a merge, you're
> asking to incorporate changes from both heads against a common merge
> base.  What does it mean when you want to merge two branches together
> but not make any changes?  Which version do you want, ours or theirs?

I believe we basically need support to apply different merge strategies
to different files.

I had similar problem a few times when I merged a long-standing branch
and, after I saw the result of merge, I was basically satisfied, except
I needed to revert a few sub-directories of the project (that gave huge
number of conflicts), to their original state, either of my current
branch, or of the branch being merged, depending on particular case. You
see, I knew exactly what I needed, yet I was not able to achieve my goal
without resorting to nasty kludges.

> Normally merges are symmetric, so if you want non-symmetric behavior,
> you have to define what it's supposed to be.

Yes, I'm ready to define what it's supposed to be. The problem is that
"git merge" won't let me, due to lack of support to apply different
merge strategies to different files.

As I see it, first step of improvements could be to support

  git merge -- <files>

where selected strategy applies only to <files>, and the rest of files
are kept intact (effectively applying "ours" strategy to them), along
with

  git merge --exclude=<files>

, to be able to exclude specific files (apply "ours" only to them)
rather than include.

[ As a side-note, please notice that after such changes, the "ours"
strategy could be deprecated (not that I think it should), as either:

   git merge <branch> --

or

   git merge --exclude=. <branch>

would do the trick. ]

The next step would then be to support

  git merge --force -- <files>

that would force to re-merge <files> with given strategy no matter what
their current status in the index is.

Even though such support would be enough for my specific use-case, it
doesn't provide suitable way to configure the default behavior. As a
more generic solution, a new syntax for "git merge" to specify what
merge strategy to apply to what files could be designed, and then
ability to put that syntax into a file for "git merge" to pick would
solve the problem of quasi-static configuration problem. Alternatively,
even more generic .gitignore way of doing things apparently could be
re-used to some degree by adding support for .gitmerge files.

-- Sergey

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 12:44   ` Sergey Organov
@ 2020-06-23 16:16     ` Philip Oakley
  2020-06-23 17:23       ` Sergey Organov
  2020-06-23 17:08     ` Elijah Newren
  1 sibling, 1 reply; 16+ messages in thread
From: Philip Oakley @ 2020-06-23 16:16 UTC (permalink / raw)
  To: Sergey Organov, brian m. carlson; +Cc: Tiran Meltser, git, Amir Yosef

On 23/06/2020 13:44, Sergey Organov wrote:
> "brian m. carlson" <sandals@crustytoothpaste.net> writes:
>
>> On 2020-06-20 at 18:21:40, Tiran Meltser wrote:
>>> Hi,
>>> This topic is quite common in various use cases (e.g. production
>>> configuration vs. staging one) and there are quite a few talks about
>>> it in the web.
>>> Nevertheless, there is no specific solution to this problem, only
>>> partial workarounds (including the famous merge driver “ours”).
>> In general, this is a hard problem.  When you perform a merge, you're
>> asking to incorporate changes from both heads against a common merge
>> base.  What does it mean when you want to merge two branches together
>> but not make any changes?  Which version do you want, ours or theirs?
> I believe we basically need support to apply different merge strategies
> to different files.
>
> I had similar problem a few times when I merged a long-standing branch
> and, after I saw the result of merge, I was basically satisfied, except
> I needed to revert a few sub-directories of the project (that gave huge
> number of conflicts), to their original state, either of my current
> branch, or of the branch being merged, depending on particular case. You
> see, I knew exactly what I needed, yet I was not able to achieve my goal
> without resorting to nasty kludges.
>
>> Normally merges are symmetric, so if you want non-symmetric behavior,
>> you have to define what it's supposed to be.
> Yes, I'm ready to define what it's supposed to be. The problem is that
> "git merge" won't let me, due to lack of support to apply different
> merge strategies to different files.
>
> As I see it, first step of improvements could be to support
>
>   git merge -- <files>
>
> where selected strategy applies only to <files>, and the rest of files
> are kept intact (effectively applying "ours" strategy to them),
So, essentially, for larger merges, this would be something like the
recent `--pathspec-from-file=<file>` series
https://public-inbox.org/git/7324e091ba7f48e286e6c35c7b7c40490e5c85d1.1576778515.git.gitgitgadget@gmail.com/
by Alexandr Miloslavskiy for the commands that did allow files to be
passed in via `--` lists.

It would still require merge to be extended to include just a
'partial-merge' or a 'file-merge' to clearly distinguish what is happening!

This still a symmetric merge, but with _author supplied_ pathspec
limiting, which is implicitly "ours" for the paths that are not merged.
(I don't believe that the pathspec file can have negative pathspecs, so..)

>  along
> with
>
>   git merge --exclude=<files>
>
> , to be able to exclude specific files (apply "ours" only to them)
> rather than include.

One difficulty of .precious lists, whether embedded or local, is the
false impression that they provide any form of security to the user, so
it needs a name that make that clear.
>
> [ As a side-note, please notice that after such changes, the "ours"
> strategy could be deprecated (not that I think it should), as either:
>
>    git merge <branch> --
>
> or
>
>    git merge --exclude=. <branch>
>
> would do the trick. ]
>
> The next step would then be to support
>
>   git merge --force -- <files>
>
> that would force to re-merge <files> with given strategy no matter what
> their current status in the index is.
Isn't this already the same as the restore/checkout?

>
> Even though such support would be enough for my specific use-case, it
> doesn't provide suitable way to configure the default behavior. As a
> more generic solution, a new syntax for "git merge" to specify what
> merge strategy to apply to what files could be designed, and then
> ability to put that syntax into a file for "git merge" to pick would
> solve the problem of quasi-static configuration problem. Alternatively,
> even more generic .gitignore way of doing things apparently could be
> re-used to some degree by adding support for .gitmerge files.
>
> -- Sergey
Philip

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 12:44   ` Sergey Organov
  2020-06-23 16:16     ` Philip Oakley
@ 2020-06-23 17:08     ` Elijah Newren
  2020-06-23 20:19       ` Sergey Organov
  2020-06-23 22:38       ` Junio C Hamano
  1 sibling, 2 replies; 16+ messages in thread
From: Elijah Newren @ 2020-06-23 17:08 UTC (permalink / raw)
  To: Sergey Organov; +Cc: brian m. carlson, Tiran Meltser, git, Amir Yosef

On Tue, Jun 23, 2020 at 5:47 AM Sergey Organov <sorganov@gmail.com> wrote:
>
> "brian m. carlson" <sandals@crustytoothpaste.net> writes:
>
> > On 2020-06-20 at 18:21:40, Tiran Meltser wrote:
> >> Hi,
> >> This topic is quite common in various use cases (e.g. production
> >> configuration vs. staging one) and there are quite a few talks about
> >> it in the web.
> >> Nevertheless, there is no specific solution to this problem, only
> >> partial workarounds (including the famous merge driver “ours”).
> >
> > In general, this is a hard problem.  When you perform a merge, you're
> > asking to incorporate changes from both heads against a common merge
> > base.  What does it mean when you want to merge two branches together
> > but not make any changes?  Which version do you want, ours or theirs?
>
> I believe we basically need support to apply different merge strategies
> to different files.
>
> I had similar problem a few times when I merged a long-standing branch
> and, after I saw the result of merge, I was basically satisfied, except
> I needed to revert a few sub-directories of the project (that gave huge
> number of conflicts), to their original state, either of my current
> branch, or of the branch being merged, depending on particular case. You
> see, I knew exactly what I needed, yet I was not able to achieve my goal
> without resorting to nasty kludges.
>
> > Normally merges are symmetric, so if you want non-symmetric behavior,
> > you have to define what it's supposed to be.
>
> Yes, I'm ready to define what it's supposed to be. The problem is that
> "git merge" won't let me, due to lack of support to apply different
> merge strategies to different files.
>
> As I see it, first step of improvements could be to support
>
>   git merge -- <files>
>
> where selected strategy applies only to <files>, and the rest of files
> are kept intact (effectively applying "ours" strategy to them), along
> with
>
>   git merge --exclude=<files>
>
> , to be able to exclude specific files (apply "ours" only to them)
> rather than include.
>
> [ As a side-note, please notice that after such changes, the "ours"
> strategy could be deprecated (not that I think it should), as either:
>
>    git merge <branch> --
>
> or
>
>    git merge --exclude=. <branch>
>
> would do the trick. ]
>
> The next step would then be to support
>
>   git merge --force -- <files>
>
> that would force to re-merge <files> with given strategy no matter what
> their current status in the index is.
>
> Even though such support would be enough for my specific use-case, it
> doesn't provide suitable way to configure the default behavior. As a
> more generic solution, a new syntax for "git merge" to specify what
> merge strategy to apply to what files could be designed, and then
> ability to put that syntax into a file for "git merge" to pick would
> solve the problem of quasi-static configuration problem. Alternatively,
> even more generic .gitignore way of doing things apparently could be
> re-used to some degree by adding support for .gitmerge files.

I think you'd have an uphill battle to convince me that this isn't
net-negative value:
  * You can just do "git merge --no-commit ...; git restore
[--source=<side>] -- <pathspec>" to do what you're talking about
above.  I don't see the need to add extra functionality to merge,
especially not functionality that duplicates restore's functionality.
  * The "ours" vs. "theirs" wording means you're going to have
intrinsic problems with rebases.  Several users will like your choice
of what "ours" means, the other half will complain that you've got it
all wrong.  I think you need to let the users decide on a case-by-case
basis, and we have a handy "git restore" command for letting them do
that already.
  * The pathspec limiting is going to be a bug factory for renaming
handling.  (The simplest form of which is just renaming a special path
to a non-special path or vice-versa and modifying both sides of
history.)  Rename handling can already get some pretty hairy corner
cases without dumping more in the mix.  I'd rather have users decide
what to do with paths that switched from being one of the special
"ours" paths to being a normal 3-way-conflict marker path.  Luckily,
we already have a command that users can use to do this: git restore.
  * I've run into "branch-specific" files in the wild and even
supported repositories that used them for years.  In my opinion, they
are almost always nasty code smells that are artifacts from
CVS/SVN-like thinking.  Although I wanted to stamp them out
immediately, there was opposition to it.  However, over time, people
removed those branch-specific files from the repository (and it wasn't
just by me or at my prodding either; many were cleaned away by others
without my involvement as other folks just found better ways to handle
things over time).  Giving special support to bad practices will just
enshrine them, which I'd rather avoid.

If someone wants to spend their time here, I can't stop them.  Just be
aware that personally, I think it'd be a bad idea to make any
merge-recursive or merge-ort changes to support this kind of thing.
(Alternatively, if you're still convinced this is a good idea, you can
consider this email a heads up about potential problem areas that you
need to address and areas where you'll need to craft some good
arguments to win over those who are skeptical.)

Hope that helps,
Elijah

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 16:16     ` Philip Oakley
@ 2020-06-23 17:23       ` Sergey Organov
  0 siblings, 0 replies; 16+ messages in thread
From: Sergey Organov @ 2020-06-23 17:23 UTC (permalink / raw)
  To: Philip Oakley; +Cc: brian m. carlson, Tiran Meltser, git, Amir Yosef

Philip Oakley <philipoakley@iee.email> writes:


[...]

>> The next step would then be to support
>>
>>   git merge --force -- <files>
>>
>> that would force to re-merge <files> with given strategy no matter what
>> their current status in the index is.
> Isn't this already the same as the restore/checkout?

I don't think it is. I meant it to be real (partial) merge, but
performed from the state where merge is already in progress, so affected
files may have specific state in the index and in the work tree, both of
which are to be discarded before the re-merge.

-- Sergey

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 17:08     ` Elijah Newren
@ 2020-06-23 20:19       ` Sergey Organov
  2020-06-23 21:46         ` Elijah Newren
  2020-06-23 22:38       ` Junio C Hamano
  1 sibling, 1 reply; 16+ messages in thread
From: Sergey Organov @ 2020-06-23 20:19 UTC (permalink / raw)
  To: Elijah Newren; +Cc: brian m. carlson, Tiran Meltser, git, Amir Yosef

Elijah Newren <newren@gmail.com> writes:

> On Tue, Jun 23, 2020 at 5:47 AM Sergey Organov <sorganov@gmail.com> wrote:

[...]

>>
>> I believe we basically need support to apply different merge strategies
>> to different files.
>>

[...]

>> > Normally merges are symmetric, so if you want non-symmetric behavior,
>> > you have to define what it's supposed to be.
>>
>> Yes, I'm ready to define what it's supposed to be. The problem is that
>> "git merge" won't let me, due to lack of support to apply different
>> merge strategies to different files.
>>
>> As I see it, first step of improvements could be to support
>>
>>   git merge -- <files>
>>
>> where selected strategy applies only to <files>, and the rest of files
>> are kept intact (effectively applying "ours" strategy to them), along
>> with
>>
>>   git merge --exclude=<files>
>>
>> , to be able to exclude specific files (apply "ours" only to them)
>> rather than include.
>>
>> [ As a side-note, please notice that after such changes, the "ours"
>> strategy could be deprecated (not that I think it should), as either:
>>
>>    git merge <branch> --
>>
>> or
>>
>>    git merge --exclude=. <branch>
>>
>> would do the trick. ]
>>
>> The next step would then be to support
>>
>>   git merge --force -- <files>
>>
>> that would force to re-merge <files> with given strategy no matter what
>> their current status in the index is.
>>
>> Even though such support would be enough for my specific use-case, it
>> doesn't provide suitable way to configure the default behavior. As a
>> more generic solution, a new syntax for "git merge" to specify what
>> merge strategy to apply to what files could be designed, and then
>> ability to put that syntax into a file for "git merge" to pick would
>> solve the problem of quasi-static configuration problem. Alternatively,
>> even more generic .gitignore way of doing things apparently could be
>> re-used to some degree by adding support for .gitmerge files.
>
> I think you'd have an uphill battle to convince me that this isn't
> net-negative value:
>
>   * You can just do "git merge --no-commit ...; git restore
> [--source=<side>] -- <pathspec>" to do what you're talking about
> above.  I don't see the need to add extra functionality to merge,
> especially not functionality that duplicates restore's functionality.

Yeah, thanks, nice to know! I didn't, as "restore" is rather recent
addition:

$ git --version
git version 2.20.1
$ git help restore
No manual entry for gitrestore

However, it probably won't help with any other merge strategy anyway,
right? E.g., think "git merge -X ours".

It's already admittedly better than nothing though!

>   * The "ours" vs. "theirs" wording means you're going to have
> intrinsic problems with rebases.  Several users will like your choice
> of what "ours" means, the other half will complain that you've got it
> all wrong.  I think you need to let the users decide on a case-by-case
> basis, and we have a handy "git restore" command for letting them do
> that already.

I don't see how rebases are affected. I only suggested enhancements to
the merge-the-procedure, the "git merge" user command. Once merge is
finished and result is committed, there is (fortunately) now way for git
to know how exactly the resulting content has been achieved.

Nor do I see why to limit decisions to "ours" vs "theirs". I meant to
support arbitrary merge strategies for different files. Generic feature.

My thought was: if git at all supports different merge strategies, why
not to support different strategies for different files? I don't see any
inherent contradiction in adding of such a feature.

>   * The pathspec limiting is going to be a bug factory for renaming
> handling.  (The simplest form of which is just renaming a special path
> to a non-special path or vice-versa and modifying both sides of
> history.)  Rename handling can already get some pretty hairy corner
> cases without dumping more in the mix.  I'd rather have users decide
> what to do with paths that switched from being one of the special
> "ours" paths to being a normal 3-way-conflict marker path.

I admittedly didn't dive into such details, but I didn't suggest to
attach any additional attributes to paths either, so there is no need to
care about renames, as far as I'm able to see.

Apparently you talk about some other feature here that I didn't suggest.

> Luckily, we already have a command that users can use to do this: git
> restore.

"git restore" is nice, but solves only very limited subset of merging
strategies we try to find solution for.

>   * I've run into "branch-specific" files in the wild and even
> supported repositories that used them for years.  In my opinion, they
> are almost always nasty code smells that are artifacts from
> CVS/SVN-like thinking.  Although I wanted to stamp them out
> immediately, there was opposition to it.  However, over time, people
> removed those branch-specific files from the repository (and it wasn't
> just by me or at my prodding either; many were cleaned away by others
> without my involvement as other folks just found better ways to handle
> things over time).  Giving special support to bad practices will just
> enshrine them, which I'd rather avoid.

I didn't suggest any specific support for "branch-specific" files, nor
to any bad practices, as far as I'm aware.

OTOH, the generic feature I suggest, as any generic feature, could
indeed be (ab)used in multiple ways, but it's not a problem of the
feature itself.

> If someone wants to spend their time here, I can't stop them. Just be
> aware that personally, I think it'd be a bad idea to make any
> merge-recursive or merge-ort changes to support this kind of thing.

Hopefully your attitude is caused by some misunderstanding of the aim of
my suggestions.

> (Alternatively, if you're still convinced this is a good idea, you can
> consider this email a heads up about potential problem areas that you
> need to address and areas where you'll need to craft some good
> arguments to win over those who are skeptical.)

I still don't see any potential problems. Could you please give an
explanatory example?

Let me try to show my point by example. Suppose I've got a merge commit
where part of files were merged with recursive strategy, part of files
-- with the same recursive strategy but with -X ours, and the rest --
with the same recursive strategy and -X theirs. What problems,
exactly, do you expect?

In fact I even fail to see how you will be able to tell it has been
achieved with suggested feature rather than by manual resolution of all
the conflicts, so there must be no additional problems here.

What do I miss?

Thanks,
-- Sergey

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 20:19       ` Sergey Organov
@ 2020-06-23 21:46         ` Elijah Newren
  2020-06-23 22:57           ` Chris Torek
  2020-06-24 19:15           ` Sergey Organov
  0 siblings, 2 replies; 16+ messages in thread
From: Elijah Newren @ 2020-06-23 21:46 UTC (permalink / raw)
  To: Sergey Organov; +Cc: brian m. carlson, Tiran Meltser, git, Amir Yosef

Hi Sergey,

On Tue, Jun 23, 2020 at 1:19 PM Sergey Organov <sorganov@gmail.com> wrote:
>
> Elijah Newren <newren@gmail.com> writes:
>
> > On Tue, Jun 23, 2020 at 5:47 AM Sergey Organov <sorganov@gmail.com> wrote:
>
> [...]
>
> >>
> >> I believe we basically need support to apply different merge strategies
> >> to different files.
> >>
>
> [...]
>
> >> > Normally merges are symmetric, so if you want non-symmetric behavior,
> >> > you have to define what it's supposed to be.
> >>
> >> Yes, I'm ready to define what it's supposed to be. The problem is that
> >> "git merge" won't let me, due to lack of support to apply different
> >> merge strategies to different files.
> >>
> >> As I see it, first step of improvements could be to support
> >>
> >>   git merge -- <files>
> >>
> >> where selected strategy applies only to <files>, and the rest of files
> >> are kept intact (effectively applying "ours" strategy to them), along
> >> with
> >>
> >>   git merge --exclude=<files>
> >>
> >> , to be able to exclude specific files (apply "ours" only to them)
> >> rather than include.
> >>
> >> [ As a side-note, please notice that after such changes, the "ours"
> >> strategy could be deprecated (not that I think it should), as either:
> >>
> >>    git merge <branch> --
> >>
> >> or
> >>
> >>    git merge --exclude=. <branch>
> >>
> >> would do the trick. ]
> >>
> >> The next step would then be to support
> >>
> >>   git merge --force -- <files>
> >>
> >> that would force to re-merge <files> with given strategy no matter what
> >> their current status in the index is.
> >>
> >> Even though such support would be enough for my specific use-case, it
> >> doesn't provide suitable way to configure the default behavior. As a
> >> more generic solution, a new syntax for "git merge" to specify what
> >> merge strategy to apply to what files could be designed, and then
> >> ability to put that syntax into a file for "git merge" to pick would
> >> solve the problem of quasi-static configuration problem. Alternatively,
> >> even more generic .gitignore way of doing things apparently could be
> >> re-used to some degree by adding support for .gitmerge files.
> >
> > I think you'd have an uphill battle to convince me that this isn't
> > net-negative value:
> >
> >   * You can just do "git merge --no-commit ...; git restore
> > [--source=<side>] -- <pathspec>" to do what you're talking about
> > above.  I don't see the need to add extra functionality to merge,
> > especially not functionality that duplicates restore's functionality.
>
> Yeah, thanks, nice to know! I didn't, as "restore" is rather recent
> addition:
>
> $ git --version
> git version 2.20.1
> $ git help restore
> No manual entry for gitrestore
>
> However, it probably won't help with any other merge strategy anyway,
> right? E.g., think "git merge -X ours".
>
> It's already admittedly better than nothing though!

Well, I mean if we're talking about adding new features to git, then
obviously we're only going to add them to new versions; in that
context, a version from a year and a half ago is ancient.  ;-)

Going on the tangent for a second: if you can, please consider
upgrading (and to something newer than the last release, 2.27.0) in
order to help the community with testing the latest features,
refactors, and performance improvements.

> >   * The "ours" vs. "theirs" wording means you're going to have
> > intrinsic problems with rebases.  Several users will like your choice
> > of what "ours" means, the other half will complain that you've got it
> > all wrong.  I think you need to let the users decide on a case-by-case
> > basis, and we have a handy "git restore" command for letting them do
> > that already.
>
> I don't see how rebases are affected. I only suggested enhancements to
> the merge-the-procedure, the "git merge" user command. Once merge is
> finished and result is committed, there is (fortunately) now way for git
> to know how exactly the resulting content has been achieved.

Sorry, the original email from Tiran wanted to be able to record
"branch-specific" files and have merge automatically handle them
differently.  You also alluded to that when you said

"""
As a
more generic solution, a new syntax for "git merge" to specify what
merge strategy to apply to what files could be designed, and then
ability to put that syntax into a file for "git merge" to pick would
solve the problem of quasi-static configuration problem. Alternatively,
even more generic .gitignore way of doing things apparently could be
re-used to some degree by adding support for .gitmerge files.
"""

Once you record the information for which files it applies to, then
you want it to happen whenever the merge machinery fires, right?
Rebasing, cherry-picking, and reverting are all created via the merge
machinery (even if they end up recording one parent instead of more).
Said another way, if merge automatically handles these special files,
either rebase/cherry-pick/revert also handle the special files
automatically or you've just created a very inconsistent and weird
design.

If you're disclaiming your last paragraph and saying that this would
only be a manual operation where the user specifies which files they
want to specially merge, then a lot of my complaints go away.
Although...

> Nor do I see why to limit decisions to "ours" vs "theirs". I meant to
> support arbitrary merge strategies for different files. Generic feature.
>
> My thought was: if git at all supports different merge strategies, why
> not to support different strategies for different files? I don't see any
> inherent contradiction in adding of such a feature.

If you're interested in re-merging specific files, why not just call
`git merge-file` to handle each one?  It supports e.g. --ours/--theirs
(similar to merge's -Xours/-Xtheirs) and could possibly add more if
there are ones missing.  So, it seems like we already have a command
for this, even if it's less well known?

> >   * The pathspec limiting is going to be a bug factory for renaming
> > handling.  (The simplest form of which is just renaming a special path
> > to a non-special path or vice-versa and modifying both sides of
> > history.)  Rename handling can already get some pretty hairy corner
> > cases without dumping more in the mix.  I'd rather have users decide
> > what to do with paths that switched from being one of the special
> > "ours" paths to being a normal 3-way-conflict marker path.
>
> I admittedly didn't dive into such details, but I didn't suggest to
> attach any additional attributes to paths either, so there is no need to
> care about renames, as far as I'm able to see.
>
> Apparently you talk about some other feature here that I didn't suggest.

Perhaps your comments on creating a ".gitmerge" file means something
different than I understood.  If it indeed does not record pathnames,
then the rename issue goes away (though then I don't understand what
its purpose is nor the rest of your comments in that paragraph where
you suggested it).  But if your .gitmerge comments did imply something
similar to .gitattributes which specified how certain paths were to be
handled, then renaming issues would certainly arise.

> >   * I've run into "branch-specific" files in the wild and even
> > supported repositories that used them for years.  In my opinion, they
> > are almost always nasty code smells that are artifacts from
> > CVS/SVN-like thinking.  Although I wanted to stamp them out
> > immediately, there was opposition to it.  However, over time, people
> > removed those branch-specific files from the repository (and it wasn't
> > just by me or at my prodding either; many were cleaned away by others
> > without my involvement as other folks just found better ways to handle
> > things over time).  Giving special support to bad practices will just
> > enshrine them, which I'd rather avoid.
>
> I didn't suggest any specific support for "branch-specific" files, nor
> to any bad practices, as far as I'm aware.
>
> OTOH, the generic feature I suggest, as any generic feature, could
> indeed be (ab)used in multiple ways, but it's not a problem of the
> feature itself.
>
> > If someone wants to spend their time here, I can't stop them. Just be
> > aware that personally, I think it'd be a bad idea to make any
> > merge-recursive or merge-ort changes to support this kind of thing.
>
> Hopefully your attitude is caused by some misunderstanding of the aim of
> my suggestions.

Well, given that the last paragraph of your first email sounds (to me)
to be contradictory to your statements in this email, it seems quite
likely I am misunderstanding something you have said.

> > (Alternatively, if you're still convinced this is a good idea, you can
> > consider this email a heads up about potential problem areas that you
> > need to address and areas where you'll need to craft some good
> > arguments to win over those who are skeptical.)
>
> I still don't see any potential problems. Could you please give an
> explanatory example?
>
> Let me try to show my point by example. Suppose I've got a merge commit
> where part of files were merged with recursive strategy, part of files
> -- with the same recursive strategy but with -X ours, and the rest --
> with the same recursive strategy and -X theirs. What problems,
> exactly, do you expect?
>
> In fact I even fail to see how you will be able to tell it has been
> achieved with suggested feature rather than by manual resolution of all
> the conflicts, so there must be no additional problems here.
>
> What do I miss?

The problems I was raising were not with the resulting end-state tree
that users can construct or what happens with those trees once
constructed.  My problems were with expected automatic behavior from
the merge machinery coupled with incomplete specifications that
sounded to me like a pile of corner cases and bugs that I'd have to
field while trying to maintain the merge machinery logic.

Oh, and I have a problem with "branch specific" files from the email
you were responding to.  I think those are a code smell.  But my
primary concern was the expectations of some new automatic behavior
out of the merge machinery and how/if it gets configured.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 17:08     ` Elijah Newren
  2020-06-23 20:19       ` Sergey Organov
@ 2020-06-23 22:38       ` Junio C Hamano
  2020-06-24 18:03         ` Sergey Organov
  1 sibling, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2020-06-23 22:38 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Sergey Organov, brian m. carlson, Tiran Meltser, git, Amir Yosef

Elijah Newren <newren@gmail.com> writes:

> I think you'd have an uphill battle to convince me that this isn't
> net-negative value:

>   * You can just do "git merge --no-commit ...; git restore ...

>   * The "ours" vs. "theirs" wording means you're going to ...

>   * The pathspec limiting is going to be a bug factory ...

>   * I've run into "branch-specific" files in the wild and even
> supported repositories that used them for years.  In my opinion, they
> are almost always nasty code smells that are artifacts from
> CVS/SVN-like thinking.  Although I wanted to stamp them out
> immediately, there was opposition to it.  However, over time, people
> removed those branch-specific files from the repository (and it wasn't
> just by me or at my prodding either; many were cleaned away by others
> without my involvement as other folks just found better ways to handle
> things over time).  Giving special support to bad practices will just
> enshrine them, which I'd rather avoid.

Also if you consider what would happen to future merges after making
such a half-merge, you would not recommend it, whether with an even
easier "feature" to encourage a bad workflow or with existing tools.

Every time you create a commit (be it a single parent commit or a
merge commit with multiple parents), you are making this statement:

    Where the histories leading to the parent commits want to go
    aligns with my goal, and with this commit, I am extending their
    effort to get us even closer to our shared goal.

After a side branch forked and worked on two parts of the system (A
and B) while the mainline did not do anything to these two parts but
worked on other parts, you look at the histories (not just the trees
of tip commits) leading to the current mainline and the tip of the
side branch, convince yourself that you agree with both of the
changes the side branch made to A and B, and because the mainline
left these two parts intact, you take their changes wholesale and
record the result in a merge commit.  Because you also made sure all
the other developments happened while the side branch forked took
you closer to your goal, you too them too, so the resulting merge
commit records a tree that is closer to either of its parents to
your goal.

And readers cannot dismiss this fact as mere philosophy; it is
fundamental and ingrained in the behaviour of Git tools,
specifically how three-way merge works.

Once you dismiss a part of what a side branch did as irrelevant by
taking "our" version for selected paths in a merge, the goal you had
when you made the merge will no longer align with the goal the folks
who worked on the side branch had.  Perhaps you only took changes to
the A part and discarded changes to the B part they made, because it
suited your goal better.  Now after the folks who care about both
parts further work on part A and B, you may try to merge their work
into the updated mainline (whose history contains the declaration
you made earlier that the work did on the B part made up to the
point you made the earlier merge is worthless).  The new merge will
use the older tip of the side branch that was partially merged with
the old merge as the merge base and will consider what was done on
the side branch (which would contain changes to both A and B---after
all they care about both A and B).  This mismatch will either cause
heavy conflicts in part B, or (worse yet) silent mismerges.

So in short, sure, you can use the existing machinery, or invent a
new "easier" machinery, to create and record such a half-merge, and
you may declare victory after creating your first such merge.  But
you left a disaster for future merges from the same side branch by
doing so.

As to handling configuration files, what you and Brian mentioned to
keep recommended template(s) in-tree and have the build procedure
copy it out and keeping the customization out of merge is the BCP.
We shouldn't butcher the tool and make it even easier to use a bad
workflow, as you said.

Thanks.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 21:46         ` Elijah Newren
@ 2020-06-23 22:57           ` Chris Torek
  2020-06-24 19:15           ` Sergey Organov
  1 sibling, 0 replies; 16+ messages in thread
From: Chris Torek @ 2020-06-23 22:57 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Sergey Organov, brian m. carlson, Tiran Meltser, git, Amir Yosef

I'm going to snip a lot here as I'm not really replying to one
specific proposal or another.  I just want to add some background:

On Tue, Jun 23, 2020 at 2:48 PM Elijah Newren <newren@gmail.com> wrote:
> Once you record the information for which files it applies to, then
> you want it to happen whenever the merge machinery fires, right?

This is, of course, already the case for merge drivers defined and
used in .gitattributes entries (though note that they don't apply to some
merge *strategies*, e.g., `-s ours` completely ignores them).

> The problems I was raising were not with the resulting end-state tree
> that users can construct or what happens with those trees once
> constructed.  My problems were with expected automatic behavior from
> the merge machinery coupled with incomplete specifications that
> sounded to me like a pile of corner cases and bugs that I'd have to
> field while trying to maintain the merge machinery logic.

This is already a bit of a problem with merge drivers in .gitattributes.
In particular, suppose we're doing a standard merge of commits H
(HEAD) and T (theirs) with respect to B (base).  If the file is named
"foo" and there is a merge driver defined for "foo", this merge driver
is completely ignored *unless* all three copies of foo differ!  And of
course there are rename issues if a file's name was foo but isn't now
or vice versa.

I do think it might be reasonable to be able to mark a merge driver
as "always use this, even if two or even all three inputs are the same".

> Oh, and I have a problem with "branch specific" files from the email
> you were responding to.  I think those are a code smell.  But my
> primary concern was the expectations of some new automatic behavior
> out of the merge machinery and how/if it gets configured.

They're not only smelly :-) ... they don't even really mean anything.
In particular, merge works not on *branches* but on *commits*.  If
we're merging commits H and T with base B, we may not be on any
branch at all (detached HEAD) and there could be anywhere from
zero to arbitrarily many branch names pointing at or containing each
of the three commits.  But of course it's common to have one branch
name for each of H and T, and that's where most people who want
this are coming from.

In any case, the merge driver stuff is useful to some people sometimes.
It might be a little more useful if you could force `git merge` to use it
even if only "their side" of the merge has changed the file since the
merge base.

Chris

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 22:38       ` Junio C Hamano
@ 2020-06-24 18:03         ` Sergey Organov
  2020-06-24 22:38           ` Junio C Hamano
  0 siblings, 1 reply; 16+ messages in thread
From: Sergey Organov @ 2020-06-24 18:03 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, brian m. carlson, Tiran Meltser, git, Amir Yosef

Junio C Hamano <gitster@pobox.com> writes:

> Elijah Newren <newren@gmail.com> writes:
>
>> I think you'd have an uphill battle to convince me that this isn't
>> net-negative value:
>
>>   * You can just do "git merge --no-commit ...; git restore ...
>
>>   * The "ours" vs. "theirs" wording means you're going to ...
>
>>   * The pathspec limiting is going to be a bug factory ...
>
>>   * I've run into "branch-specific" files in the wild and even
>> supported repositories that used them for years.  In my opinion, they
>> are almost always nasty code smells that are artifacts from
>> CVS/SVN-like thinking.  Although I wanted to stamp them out
>> immediately, there was opposition to it.  However, over time, people
>> removed those branch-specific files from the repository (and it wasn't
>> just by me or at my prodding either; many were cleaned away by others
>> without my involvement as other folks just found better ways to handle
>> things over time).  Giving special support to bad practices will just
>> enshrine them, which I'd rather avoid.
>
> Also if you consider what would happen to future merges after making
> such a half-merge, you would not recommend it, whether with an even
> easier "feature" to encourage a bad workflow or with existing tools.
>
> Every time you create a commit (be it a single parent commit or a
> merge commit with multiple parents), you are making this statement:
>
>     Where the histories leading to the parent commits want to go
>     aligns with my goal, and with this commit, I am extending their
>     effort to get us even closer to our shared goal.
>
> After a side branch forked and worked on two parts of the system (A
> and B) while the mainline did not do anything to these two parts but
> worked on other parts, you look at the histories (not just the trees
> of tip commits) leading to the current mainline and the tip of the
> side branch, convince yourself that you agree with both of the
> changes the side branch made to A and B, and because the mainline
> left these two parts intact, you take their changes wholesale and
> record the result in a merge commit.  Because you also made sure all
> the other developments happened while the side branch forked took
> you closer to your goal, you too them too, so the resulting merge
> commit records a tree that is closer to either of its parents to
> your goal.
>
> And readers cannot dismiss this fact as mere philosophy; it is
> fundamental and ingrained in the behaviour of Git tools,
> specifically how three-way merge works.
>
> Once you dismiss a part of what a side branch did as irrelevant by
> taking "our" version for selected paths in a merge, the goal you had
> when you made the merge will no longer align with the goal the folks
> who worked on the side branch had.  Perhaps you only took changes to
> the A part and discarded changes to the B part they made, because it
> suited your goal better.  Now after the folks who care about both
> parts further work on part A and B, you may try to merge their work
> into the updated mainline (whose history contains the declaration
> you made earlier that the work did on the B part made up to the
> point you made the earlier merge is worthless).  The new merge will
> use the older tip of the side branch that was partially merged with
> the old merge as the merge base and will consider what was done on
> the side branch (which would contain changes to both A and B---after
> all they care about both A and B).  This mismatch will either cause
> heavy conflicts in part B, or (worse yet) silent mismerges.

What is suggested is exactly a way to deal with heavy merge conflicts in
the first place, in particular, in the example you use, by telling git
that we are not interested in the side-changes in a given set of files.
Never.

If we change our mind later, we will simply need to start merging from
the point before that old, now rendered wrong, decision took place.

OTOH, if one tries to abuse the feature for different purposes, it will
hurt sooner than later, no questions.

>
> So in short, sure, you can use the existing machinery, or invent a
> new "easier" machinery, to create and record such a half-merge, and
> you may declare victory after creating your first such merge.  But
> you left a disaster for future merges from the same side branch by
> doing so.

I think I at least understand most of what you said, except I wasn't
able to figure what the definition of "half-merge", or "partial merge"
is.

To clarify, could you please tell if plain

   git merge -s ours

is a "partial merge" from your point of view?

If you think it is not, then what about:

  git merge -X ours

? Is it a "partial merge"?

Thanks,
-- Sergey

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-23 21:46         ` Elijah Newren
  2020-06-23 22:57           ` Chris Torek
@ 2020-06-24 19:15           ` Sergey Organov
  1 sibling, 0 replies; 16+ messages in thread
From: Sergey Organov @ 2020-06-24 19:15 UTC (permalink / raw)
  To: Elijah Newren; +Cc: brian m. carlson, Tiran Meltser, git, Amir Yosef

Hi Elijah,

Elijah Newren <newren@gmail.com> writes:

> Hi Sergey,
>
> On Tue, Jun 23, 2020 at 1:19 PM Sergey Organov <sorganov@gmail.com> wrote:

[...]

>> I don't see how rebases are affected. I only suggested enhancements to
>> the merge-the-procedure, the "git merge" user command. Once merge is
>> finished and result is committed, there is (fortunately) now way for git
>> to know how exactly the resulting content has been achieved.
>
> Sorry, the original email from Tiran wanted to be able to record
> "branch-specific" files and have merge automatically handle them
> differently.  You also alluded to that when you said
>
> """
> As a
> more generic solution, a new syntax for "git merge" to specify what
> merge strategy to apply to what files could be designed, and then
> ability to put that syntax into a file for "git merge" to pick would
> solve the problem of quasi-static configuration problem. Alternatively,
> even more generic .gitignore way of doing things apparently could be
> re-used to some degree by adding support for .gitmerge files.
> """
>
> Once you record the information for which files it applies to, then
> you want it to happen whenever the merge machinery fires, right?

No. I didn't mean it, no way. I wanted only "git merge" to be affected.

> Rebasing, cherry-picking, and reverting are all created via the merge
> machinery (even if they end up recording one parent instead of more).
> Said another way, if merge automatically handles these special files,
> either rebase/cherry-pick/revert also handle the special files
> automatically or you've just created a very inconsistent and weird
> design.

I disagree. The fact that all of the mentioned commands reuse internal
merge implementation is a good thing, but it's irrelevant to the case at
hand. I never merge side-branches with either of
rebase/cherry-pick/revert, so it's only logical to ask for specific
branch-merging functionality only from "git merge".

I don't even want to think for now if it could be useful in
rebase/cherry-pick/revert/whatever, as it's already difficult enough.

As a side note, if anything, in my POV, having both rebase and
cherry-pick in porcelain is an overkill. Effectively, 'rebase' is a
'cherry-pick' on steroids, so adding a --cherry option to 'rebase' seems
to be logical.

>
> If you're disclaiming your last paragraph and saying that this would
> only be a manual operation where the user specifies which files they
> want to specially merge, then a lot of my complaints go away.

Nothing to disclaim, I think. What I thought was that it will affect
things automatically, but only for "git merge". Apparently generic merge
machinery will need support for this, but it will be used only for "git
merge", at least for a start. Alternatively, there could be generic
option that will turn this handling on, and this option will be turned
on by default only for "git merge". I'm not familiar with Git
implementation enough to even try suggest the right way to implement it
though.

> Although...
>
>> Nor do I see why to limit decisions to "ours" vs "theirs". I meant to
>> support arbitrary merge strategies for different files. Generic feature.
>>
>> My thought was: if git at all supports different merge strategies, why
>> not to support different strategies for different files? I don't see any
>> inherent contradiction in adding of such a feature.
>
> If you're interested in re-merging specific files, why not just call
> `git merge-file` to handle each one?  It supports e.g. --ours/--theirs
> (similar to merge's -Xours/-Xtheirs) and could possibly add more if
> there are ones missing.  So, it seems like we already have a command
> for this, even if it's less well known?

merge-file is likely some low-level utility... check... yeah, it is.
Extremely low-level. Three-way merge of 3 /files/. How does it help? How
much error-prone scripting will I need to get to the point of any
suitable result?

To me what you suggest here is basically what I've described as kludgy
way of achieving the goal. I can probably also make merges with
different strategies in 2 different repositories, then copy files
between them. Does it mean I already have all the needed tools to get
the job done?

Please consider the problem: I did a regular merge, and by analysis of
the resulting conflicts I realized I'd need to visit a few tens of files
and resolve conflicts exactly the way -X ours would. Suppose, for
simplicity, that all these files are in some sub-directory <subdir>.

git merge --force -X ours -- <subdir>

would solve this immediately, if it existed. Honestly, I can't even
estimate what would I need to do to achieve it using "git merge-file". I
mean, I guess it's possible, yet I don't believe it's practical.

>> >   * The pathspec limiting is going to be a bug factory for renaming
>> > handling.  (The simplest form of which is just renaming a special path
>> > to a non-special path or vice-versa and modifying both sides of
>> > history.)  Rename handling can already get some pretty hairy corner
>> > cases without dumping more in the mix.  I'd rather have users decide
>> > what to do with paths that switched from being one of the special
>> > "ours" paths to being a normal 3-way-conflict marker path.
>>
>> I admittedly didn't dive into such details, but I didn't suggest to
>> attach any additional attributes to paths either, so there is no need to
>> care about renames, as far as I'm able to see.
>>
>> Apparently you talk about some other feature here that I didn't suggest.
>
> Perhaps your comments on creating a ".gitmerge" file means something
> different than I understood.  If it indeed does not record pathnames,
> then the rename issue goes away (though then I don't understand what
> its purpose is nor the rest of your comments in that paragraph where
> you suggested it).  But if your .gitmerge comments did imply something
> similar to .gitattributes which specified how certain paths were to be
> handled, then renaming issues would certainly arise.

Well, I had no use for .gitattributes, so I didn't even recall they
exist. Maybe it's where needed support could be defined, so that
existing renames handling machinery is simply reused without additional
efforts. Will it work right now if I define custom merge driver that
does "git merge -X ours" and then assign it to the set of files? It'd
still be a kludge, but one that proves the point that such support could
be implemented without much effort.

OTOH, as I already said, my own use-case doesn't need any permanent
configuration, so what I say about it is mostly just thinking aloud. In
particular, the .gitattributes trick above is again too complex to solve
a casual but heavy problem I sometimes have, though I think I'd still
use it lacking better way.

Thanks,
-- Sergey

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-24 18:03         ` Sergey Organov
@ 2020-06-24 22:38           ` Junio C Hamano
  2020-06-25 11:46             ` Sergey Organov
  0 siblings, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2020-06-24 22:38 UTC (permalink / raw)
  To: Sergey Organov
  Cc: Elijah Newren, brian m. carlson, Tiran Meltser, git, Amir Yosef

Sergey Organov <sorganov@gmail.com> writes:

> To clarify, could you please tell if plain
>
>    git merge -s ours
>
> is a "partial merge" from your point of view?

It is not even "partial".

The merge strategy "-s ours" is a way to cauterize a side branch as
dead-end, declaring that everything that has ever been done on that
side branch up to the point of the merge is not interesting and we'd
never want to look at anything that builds on it.

It has its uses, though.  After doing so, "git log --all ^mainline"
or "git branch --not-merged release" would not show such a
cauterized branch; it is a good way to "hide" the branch that you
deem a dead-end when you cannot remove it.  But of course you do not
want to ever build on such a side branch after doing so.

> If you think it is not, then what about:
>
>   git merge -X ours

It is not even a sensible merge.  It takes their changes where we
didn't touch, but it takes our change without even looking at what
they did when the changes overlap.  It's like saying

	let's take as much automerge results as possible to salvage
	their changes where our work does not overlap with what they
	did on their side branch, but in places that textually
	conflict, I would not bother trying to understand what they
	wanted to do well enough to be able to reimplement it for
	them within the context of the current code we updated to.

It is better than letting monkeys type randomly and claim that they
resolved conflicts, but not by a large margin ;-)

See also https://lore.kernel.org/git/7vr69r8sqk.fsf@gitster.siamese.dyndns.org/
that is more than 10 years old.

Imagine you have two (for simplicity) areas of interest, each is
worked by a different team, A and B, whose work are in directories
dir-A and dir-B of the project.  The teams work on their own topic
branches and from time to time merge to the "development" branch for
integration testing.  Time flows from left to right.


    ---A---A---A---A---A	team A
                \       \
      ---X---X---X---X---X	integration testing
            /       /
    ---B---B---B---B		team B

After a while, team A may be tempted to say "we are done, so let's
merge our work to the release branch", but the work product of team
B may be far from ready.

If teams have been keeping good branch hygiene, such a merge to
release branch may be done by merging the rightmost commit on A
branch directly to the release branch and there is no need for a
"partial merge that merges only dir-A while ignoring dir-B".  But if
we start supporting such a feature, it becomes tempting to use such
a "(mis)feature" to merge the rightmost commit on the integration
branch X to the release branch.  Some may find it even necessary
because A's branch may contain backmerges from the integration
testing branch, hence contaminated by unfinished work by team B.

The resulting tree of such a partial merge from integration testing
branch may be the same as a proper "merge of topic branch A into
release" for this "first" merge by team A, but the consequence it
leaves for team B would be nasty.  After building a bit more on what
they had on the branch B, it may become ready to release their part,
but because of the partial merge that declared that team B's effort
on dir-B before the point of the first merge is worthless, the
release branch, even though it would already have the four commits
labelled as B in the picture contained, has none of the actual
changes reflected in its tree.  The result would be like cherry
picking only recent work on team B's branch, not the whole thing.

And that is why such a "pathspec limited" merge is a way to
disaster that encourages a bad workflow.

Thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Request for adding a simple mechanism to exclude files from Git merge operation
  2020-06-24 22:38           ` Junio C Hamano
@ 2020-06-25 11:46             ` Sergey Organov
  0 siblings, 0 replies; 16+ messages in thread
From: Sergey Organov @ 2020-06-25 11:46 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, brian m. carlson, Tiran Meltser, git, Amir Yosef

Junio C Hamano <gitster@pobox.com> writes:

> Sergey Organov <sorganov@gmail.com> writes:
>
>> To clarify, could you please tell if plain
>>
>>    git merge -s ours
>>
>> is a "partial merge" from your point of view?
>
> It is not even "partial".

OK, get it, thanks!

I asked for clarification because it /is/ possible to interpret such
merge as "partial" in the sense that it gets only /part/ of changes,
discarding those that were introduced on the side branch.

>
> The merge strategy "-s ours" is a way to cauterize a side branch as
> dead-end, declaring that everything that has ever been done on that
> side branch up to the point of the merge is not interesting and we'd
> never want to look at anything that builds on it.
>
> It has its uses, though.  After doing so, "git log --all ^mainline"
> or "git branch --not-merged release" would not show such a
> cauterized branch; it is a good way to "hide" the branch that you
> deem a dead-end when you cannot remove it.  But of course you do not
> want to ever build on such a side branch after doing so.
>

I think the usefulness of the feature might happen to be somewhat wider,
yet I'm to avoid arguing, to scatter no attention.

>> If you think it is not, then what about:
>>
>>   git merge -X ours
>
> It is not even a sensible merge.

I don't believe one could tell out of context, see below.

Anyway, the question was not if it's good, bad, or sensible. Suppose I
do such a "non-sensible" merge, is it a "partial merge" or not?

> It takes their changes where we didn't touch, but it takes our change
> without even looking at what they did when the changes overlap.

Sure, and that happens to be exactly what I need from Git when I do such
merge, because I did look at all the 137 conflicts and found none where
I need different resolution; and yes, I'm too lazy to resolve all 137 by
hand. Makes sense? Is my merge "partial" /now/?

Getting back to technical discussion, can we come up with a useful
definition of "partial merge" at all? Honestly, I can't, and unless
somebody else does, I'm inclined to consider it to be an arbitrary label
being put on selected merge examples for the sake of argument.

Thanks,
-- Sergey

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-06-25 11:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-20 18:21 Request for adding a simple mechanism to exclude files from Git merge operation Tiran Meltser
2020-06-21 15:43 ` Philip Oakley
2020-06-22 18:42   ` [E] " Tiran Meltser
2020-06-22 19:41 ` brian m. carlson
2020-06-23 12:44   ` Sergey Organov
2020-06-23 16:16     ` Philip Oakley
2020-06-23 17:23       ` Sergey Organov
2020-06-23 17:08     ` Elijah Newren
2020-06-23 20:19       ` Sergey Organov
2020-06-23 21:46         ` Elijah Newren
2020-06-23 22:57           ` Chris Torek
2020-06-24 19:15           ` Sergey Organov
2020-06-23 22:38       ` Junio C Hamano
2020-06-24 18:03         ` Sergey Organov
2020-06-24 22:38           ` Junio C Hamano
2020-06-25 11:46             ` Sergey Organov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.