git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
@ 2007-11-28 15:48 Bill Priest
  2007-11-28 15:53 ` Jakub Narebski
  2007-11-28 20:08 ` Junio C Hamano
  0 siblings, 2 replies; 7+ messages in thread
From: Bill Priest @ 2007-11-28 15:48 UTC (permalink / raw
  To: git

All,
  I merged from one branch to another and had lots of
conflicts.  I've resolved a set of files from the
conflicts (in a directory) and did a git-add on this
set of files.  I wasn't able to commit these files. 
On IRC I was told that all files must be resolved
before I can commit any of them.  This seems pretty
limiting.  Why is a commit after a merge all or
nothing; I thought that git  figured out merges and
such by the differences between files??

Bill



      ____________________________________________________________________________________
Be a better sports nut!  Let your teams follow you 
with Yahoo Mobile. Try it now.  http://mobile.yahoo.com/sports;_ylt=At9_qDKvtAbMuh1G1SQtBI7ntAcJ

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

* Re: can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
  2007-11-28 15:48 Bill Priest
@ 2007-11-28 15:53 ` Jakub Narebski
  2007-11-28 20:08 ` Junio C Hamano
  1 sibling, 0 replies; 7+ messages in thread
From: Jakub Narebski @ 2007-11-28 15:53 UTC (permalink / raw
  To: git

Bill Priest wrote:

> All,
>   I merged from one branch to another and had lots of
> conflicts.  I've resolved a set of files from the
> conflicts (in a directory) and did a git-add on this
> set of files.  I wasn't able to commit these files. 
> On IRC I was told that all files must be resolved
> before I can commit any of them.  This seems pretty
> limiting.  Why is a commit after a merge all or
> nothing; I thought that git  figured out merges and
> such by the differences between files??

You have to resolve _conflicts_ only. The rest is added
automatically. See git-status, git diff --merge,
git ls-files -u.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

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

* Re: can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
       [not found] <251604.8861.qm@web55007.mail.re4.yahoo.com>
@ 2007-11-28 16:55 ` Jakub Narebski
  0 siblings, 0 replies; 7+ messages in thread
From: Jakub Narebski @ 2007-11-28 16:55 UTC (permalink / raw
  To: Bill Priest; +Cc: git

Please do not toppost, and try not to break quoted lines, please.
Thanks in advance.

On Wed, 28 Nov 2007, Bill Priest wrote:
> --- Jakub Narebski <jnareb@gmail.com> wrote:
>> Bill Priest wrote:
>> 
>>>   I merged from one branch to another and had lots of
>>> conflicts.  I've resolved a set of files from the
>>> conflicts (in a directory) and did a git-add on this
>>> set of files.  I wasn't able to commit these files. 
>>> On IRC I was told that all files must be resolved
>>> before I can commit any of them.  This seems pretty
>>> limiting.  Why is a commit after a merge all or
>>> nothing; I thought that git  figured out merges and
>>> such by the differences between files??
>> 
>> You have to resolve _conflicts_ only. The rest is
>> added
>> automatically. See git-status, git diff --merge,
>> git ls-files -u.

>    I understand that git requires this.  My question
> is   git enforcing policy or is there something
> "magic" about a commit after a merge.  What if I want
> to make an independent change and check it in on the
> same branch before I am finished with the merge? 

A little technical information about failed merge.

First, git tries to merge as mauch as it can automatically,
doing tree-level merge and trying three-way file-level merge
if necessary. Everything that merges cleanly is automatically
added to staging area.

For each file that has unresolved conflicts git adds to staging
are all (three) versions of file: original, from merged in
branch, and common ancestor version, as stages 1, 2, 3 (not
necessary in this order: see documentation). Additionally it
leaves partially merged file in working area with RCS-like
conflicts markes in it. (Note that default checking before
commits refuses to check in file with conflict markers; see
documentation how to force commit anyway).

Additionally git records the fact that it is in the midle of merge
by recording branch(es) merged in in .git/MERGE_HEAD.


To resolve conflicts you have to bring file to some version,
removing conflict markers, add this version using "git add",
then commit.


You can try to git-stash partially done merge; if it doesn't
work send us bugreport.

-- 
Jakub Narebski
Poland

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

* Re: can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
       [not found] <993937.9873.qm@web55013.mail.re4.yahoo.com>
@ 2007-11-28 18:11 ` Jakub Narebski
  0 siblings, 0 replies; 7+ messages in thread
From: Jakub Narebski @ 2007-11-28 18:11 UTC (permalink / raw
  To: Bill Priest; +Cc: git

Bill Priest wrote:

> I understand what git is doing in terms of trying to
> merge.  But it sounds like it is enforcing policy on
> the merge by not allowing me to check in files as I
> resolve them.  I have two separate branches w/ a
> similar but not identical hardware platform where I
> will always get conflicts when I merge back and forth.
>  Usually I cherry-pick between the two branches and
> this works until there are massive changes on one
> branch w/o time to move the changes to the other.  In
> the latter case I do a merge and live w/ resolving
> conflicts.I guess w/ this workflow I have more
> conflicts than is "normal".  
> 
> It seems pretty heavy handed to force all merges to be
> complete before I can commit any files; git knows
> which files are unmerged.  Does git track which files
> have been merged w/ conflicts?  I'd like the option to
> be able to check in files that I have indicated have
> conflicts resolved (maybe w/ a flag to bypass the
> checking).

Yes, git does track which files have conflict, but I don't
think it does track which files were merged on file-level
without conflicts.

The problem is that git remember which files are yet not
resolved, and remembers that it is in the middle of the
merge by remembering parents of a merge. So I think if you
want to commit before doing merge, you would have to move
MERGE_HEAD away, and commit specifying paths using
"git commit <file1> <file2>". Or you can always resort
to low-level plumbing, for example creating temporary
staging area (index) etc.

But if you want to just make some commit to be cherry-picked
for example before merge, I think it would be easier to just
stash away merge, do a commit, then unstash it.

-- 
Jakub Narebski
Poland

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

* Re: can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
  2007-11-28 15:48 Bill Priest
  2007-11-28 15:53 ` Jakub Narebski
@ 2007-11-28 20:08 ` Junio C Hamano
  1 sibling, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2007-11-28 20:08 UTC (permalink / raw
  To: Bill Priest; +Cc: git

Bill Priest <priestwilliaml@yahoo.com> writes:

>   I merged from one branch to another and had lots of
> conflicts.  I've resolved a set of files from the
> conflicts (in a directory) and did a git-add on this
> set of files.  I wasn't able to commit these files. 
> On IRC I was told that all files must be resolved
> before I can commit any of them.  This seems pretty
> limiting.

You have two parallel development lines that lead to A and B and trying
to come up with a "merge" M:

         o---o---A
        /         \
    ---o---o---B---M

What property should the merge commit "M" have?  It must keep the
changes made on the upper line to make it better than B, and it must
keep the changes made on the lower line to make it better than A.

Let's say both upper and lower lines of development touched files frotz
and xyzzy in overlapping, different ways.  You try to merge A while you
are at B and see conflicts in these two files.

Let's say you resolved frotz; the contents in frotz is in a desired
shape, i.e you have the changes you want from the line led to A and the
other line led to B.  But you haven't resolved xyzzy yet.

You seem to want to make this half-resolved state as a commit.  First
question: what contents would you want to commit for xyzzy?

If you commit the contents from B (because you started from it), then it
should not be recorded as a proper merge.  If you did so, merging that
back to A would obliterate all the work done up to A to file xyzzy:

         o---o---A...X
        /         \ .
    ---o---o---B---*
 
because merge base of A and * (I am marking it differently because such
an incomplete merge should not be made) is A, so the result (X) will be
the half-merge * itself (fast forward).  That's not a merge as it is not
better than A -- you discarded improvements made to xyzzy by people who
built up to A.

This is inherent to what a merge is.  With proper understanding of what
a merge is, you would not feel this limiting at all.

Having said that, I think something like the following _could_ be done,
although I do not know if it makes much sense.

(1) Try merge, see it conflict, resolve only a part of it, and record
    the result as "WIP to merge in A".  Do not record it as a merge, as
    it is not.  diff between B and M will contain a squash merge of A on
    top of B minus the changes to the path xyzzy.

         o---o---A
        /         
    ---o---o---B---M

(2) Fix up the conflicts in xyzzy to resolve the conflicts fully, and
    record the result as "Final merge of A into B".  This should be
    recorded as a merge, as the result is "keeping changes done on both
    branches to come up with something better than either of them."

         o---o---A---,
        /             \
    ---o---o---B---M---N

If you look at the topology a bit differently, the above actually makes
some sense:

         .---o---o---A
        /             \
    ---o---o---B---M---N

That is, instead of merging A into B, you made "preparatory changes" to
branch B in order to make it easier to merge A.  That's what the commit
M is about.

Then you merge A on top of M.  In reality, because the difference
between B to M contains most of the squash merge of A into B, such a
merge N will contain many accidental clean merges.  But in git,
accidental clean merges are not a problem (people can apply the same
patch to their trees and later their branches can be merged).

But "git commit" after a conflicted merge will always create a merge,
and there is no canned option to do multi-step merge like the above.

You can still do that by hand, by doing something like:

	$ git merge --squash A
        $ resolve only partly
        $ git commit -m 'Prepare to merge A'
        $ git reset --hard
        $ git merge A
	$ resolve the rest
        $ git commit -m 'Fully merged A'

For such a multi-step merge to make sense, the change between B---M
should make sense by itself for people who have to read such a history
later.  Such a half-a-squash-merge may probably not make sense by itself
in most cases, so I suspect the above workflow would not be useful in
general.

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

* Re: can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
@ 2007-11-29  4:10 Bill Priest
  0 siblings, 0 replies; 7+ messages in thread
From: Bill Priest @ 2007-11-29  4:10 UTC (permalink / raw
  To: Junio C Hamano; +Cc: git

On Wed, 28 Nov 2007 12:08:40 -0800
Junio C Hamano <gitster@pobox.com> wrote:

> Bill Priest <priestwilliaml@yahoo.com> writes:
> 
> >   I merged from one branch to another and had lots
of
> > conflicts.  I've resolved a set of files from the
> > conflicts (in a directory) and did a git-add on
this
> > set of files.  I wasn't able to commit these
files. 
> > On IRC I was told that all files must be resolved
> > before I can commit any of them.  This seems
pretty
> > limiting.
> 
> You have two parallel development lines that lead to
A and B and trying
> to come up with a "merge" M:
> 
>          o---o---A
>         /         \
>     ---o---o---B---M
> 
> What property should the merge commit "M" have?  It
must keep the
> changes made on the upper line to make it better
than B, and it must
> keep the changes made on the lower line to make it
better than A.

Ok.  One thing I probably wasn't clear on is these are
two distinct
product lines that share a great amount of code;
however, much of the
code is "incompatible".  The two branches will never
be "merged" into
one "mainline" as the underlying hardware is by
definition
incompatible.  In theory I could use a bunch of
conditional compilation
to unify the two lines; however, this means that every
time I make a
change to one branch I have to make sure that it
doesn't break the
other one.  It would have been better if the code was
modularized
better to just include different files for the two
versions;
unfortunately this is easier said than done.  I guess
you could think
of it line a 2.4 kernel vs. a 2.6 kernel; but in the
same repository.
So to sum it up there are changes in branch A that
will never go into
branch B (and vice versa); however, there are a number
of changes that
need to go into both.  Unfortunately the rest of my
team uses
subversion and isn't even aware that I am using git
(we recently switch
to subversion from cvs, so it is a hard sell to
management to switch
again).  I'm responsible for keeping bug fixes and new
features in both
product lines and I found subversion's merging to be
utterly useless. 
> Let's say both upper and lower lines of development
touched files frotz
> and xyzzy in overlapping, different ways.  You try
to merge A while you
> are at B and see conflicts in these two files.
> 
> Let's say you resolved frotz; the contents in frotz
is in a desired
> shape, i.e you have the changes you want from the
line led to A and the
> other line led to B.  But you haven't resolved xyzzy
yet.
> 
> You seem to want to make this half-resolved state as
a commit.  First
> question: what contents would you want to commit for
xyzzy?

As an example there is a directory in the tree that is
a program that
runs on a PC (vs. the other stuff that runs on
embedded processors) it
shares a handful of include files w/ the embedded side
for packet
definition but it is otherwise completely separate
from the programs
that run on the embedded processors.  Once I complete
merging of this
directory and it builds it is ready to go.  The
remaining merges have
no effect on this PC based program.  I'm not sure if
it is possible or
not but if I could merge this directory and below
(does git support
this??) it might be one way of handling it or if I
cherry-pick'ed it
that could also work.  This isn't always feasible as
the other users
often check in wholesale changes into subversion as
one change set
(remember that these are former cvs users that have
lots of bad habits
to lose).  It would be great if branches were created
for each
"logical" change and checked in in one changeset; this
seems to be what
git is expecting (in a perfect world this would always
be the case).

> 
> If you commit the contents from B (because you
started from it), then it
> should not be recorded as a proper merge.  If you
did so, merging that
> back to A would obliterate all the work done up to A
to file xyzzy:
> 
>          o---o---A...X
>         /         \ .
>     ---o---o---B---*
>  
> because merge base of A and * (I am marking it
differently because such
> an incomplete merge should not be made) is A, so the
result (X) will be
> the half-merge * itself (fast forward).  That's not
a merge as it is not
> better than A -- you discarded improvements made to
xyzzy by people who
> built up to A.
> 
> This is inherent to what a merge is.  With proper
understanding of what
> a merge is, you would not feel this limiting at all.

I've used clearcase in the past and although there
were many things I
didn't like about it (big, slow, costs $$$$, network
pig, needs a super
server, etc.) it did allow commits of files at any
time and tracked the
files that were merged independently.  I know that git
tracks changes
and not files; but in the end you have to pick file(s)
or pieces of
them to be committed; having the tool restrict me from
committing files
because of the way it tracks merges IS limiting IMHO. 
I guess the big
difference is that in kernel land you can reject
patches until they are
broken up into "atomic" pieces (I don't really have
the option of
reversing the subversion commit and turning it into
"atomic" commits).

> Having said that, I think something like the
following _could_ be done,
> although I do not know if it makes much sense.
> 
> (1) Try merge, see it conflict, resolve only a part
of it, and record
>     the result as "WIP to merge in A".  Do not
record it as a merge, as
>     it is not.  diff between B and M will contain a
squash merge of A on
>     top of B minus the changes to the path xyzzy.
> 
>          o---o---A
>         /         
>     ---o---o---B---M
> 
> (2) Fix up the conflicts in xyzzy to resolve the
conflicts fully, and
>     record the result as "Final merge of A into B". 
This should be
>     recorded as a merge, as the result is "keeping
changes done on both
>     branches to come up with something better than
either of them."
> 
>          o---o---A---,
>         /             \
>     ---o---o---B---M---N
> 
> If you look at the topology a bit differently, the
above actually makes
> some sense:
> 
>          .---o---o---A
>         /             \
>     ---o---o---B---M---N
> 
> That is, instead of merging A into B, you made
"preparatory changes" to
> branch B in order to make it easier to merge A. 
That's what the commit
> M is about.
> 
> Then you merge A on top of M.  In reality, because
the difference
> between B to M contains most of the squash merge of
A into B, such a
> merge N will contain many accidental clean merges. 
But in git,
> accidental clean merges are not a problem (people
can apply the same
> patch to their trees and later their branches can be
merged).
> 
> But "git commit" after a conflicted merge will
always create a merge,
> and there is no canned option to do multi-step merge
like the above.
> 
> You can still do that by hand, by doing something
like:
> 
> 	$ git merge --squash A
>         $ resolve only partly
>         $ git commit -m 'Prepare to merge A'
>         $ git reset --hard
>         $ git merge A
> 	$ resolve the rest
>         $ git commit -m 'Fully merged A'

Ok.  I did a git merge --squash.  So I should be able
to try this.
After I resolve only partly; I'm assuming that I git
checkout HEAD any
files that I don't want yet and then do the commit? 
Assuming that I
commit the partial after throwing away any merges that
I wasn't ready
to do (via git checkout HEAD); what does the "git
reset --hard" do? 
> For such a multi-step merge to make sense, the
change between B---M
> should make sense by itself for people who have to
read such a history
> later.  Such a half-a-squash-merge may probably not
make sense by itself
> in most cases, so I suspect the above workflow would
not be useful in
> general.

I would agree for the case where in the end you really
only have one
product; but again think like you have a 2.4 kernel
and a 2.6 kernel in
the same repository.  For most embedded development
(I've been doing it
for 20+ years) there is always newer hardware that
changes processors,
add features, gets all the new development while the
"old" production
board is still shipping and in customers hands and
needs bug fixes and
the occassional new feature.  It doesn't make sense to
have two
separate repositories when much of the code is the
same and is likely
to need the same fixes.

Junio,
	Thanks for your time and insight; git has already
saved me
countless hours and has certainly come a long way in a
very short
time.  I'll give your multi-step merge a shot and see
how well it works
for my code base.  I'm sure there are better ways to
structure my code
base to get what I am looking for; but as is usually
the case the rules
of the game have changed as I have been playing it
(the old hardware
was supposed to die and never be touched again; HA
HA).

Regards,

Bill




      ____________________________________________________________________________________
Be a better pen pal. 
Text or chat with friends inside Yahoo! Mail. See how.  http://overview.mail.yahoo.com/

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

* Re: can't commit files that have been git add'ed because "fatal: you need to resolve your current index first"
@ 2007-11-30 16:32 Bill Priest
  0 siblings, 0 replies; 7+ messages in thread
From: Bill Priest @ 2007-11-30 16:32 UTC (permalink / raw
  To: Junio C Hamano; +Cc: git

On Wed, 28 Nov 2007 12:08:40 -0800
Junio C Hamano <gitster@pobox.com> wrote:

> You can still do that by hand, by doing something
like:
> 
> 	$ git merge --squash A
>         $ resolve only partly
>         $ git commit -m 'Prepare to merge A'
>         $ git reset --hard
>         $ git merge A
> 	$ resolve the rest
>         $ git commit -m 'Fully merged A'
> 
> For such a multi-step merge to make sense, the
change between B---M
> should make sense by itself for people who have to
read such a history
> later.  Such a half-a-squash-merge may probably not
make sense by itself
> in most cases, so I suspect the above workflow would
not be useful in
> general.
> 

Junio,
	I resolved all the merges and then committed
different files as groups to make it easy to
cherry-pick after this merge.  Does this "mess up" the
merge info?  What does the "git reset --hard" do after
the commit (I'm assuming it throws away the
non-resolved changes not committed)?  But from my
experience git wouldn't let me do the commit above it
w/o first fixing the conflicts.

	Am I mis-interpreting your example or are you saying
that you think git would let me do the commit w/o
resolving all conflicts?

Bill



      ____________________________________________________________________________________
Get easy, one-click access to your favorites. 
Make Yahoo! your homepage.
http://www.yahoo.com/r/hs 

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

end of thread, other threads:[~2007-11-30 16:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-29  4:10 can't commit files that have been git add'ed because "fatal: you need to resolve your current index first" Bill Priest
  -- strict thread matches above, loose matches on Subject: below --
2007-11-30 16:32 Bill Priest
     [not found] <993937.9873.qm@web55013.mail.re4.yahoo.com>
2007-11-28 18:11 ` Jakub Narebski
     [not found] <251604.8861.qm@web55007.mail.re4.yahoo.com>
2007-11-28 16:55 ` Jakub Narebski
2007-11-28 15:48 Bill Priest
2007-11-28 15:53 ` Jakub Narebski
2007-11-28 20:08 ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).