[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: VC mode and git

From: Stephen J. Turnbull
Subject: Re: VC mode and git
Date: Tue, 31 Mar 2015 23:02:16 +0900

Alan Mackenzie writes:

 > I lost some changes in my working directory after doing something
 > like git pull.  I can't remember the details any more.

"Something like."  "Can't remember."  That's the real problem, and git
(or whatever the VCS in use is, but for Emacs it's git) is the
solution.  "Commit early, commit often", and you won't have to worry
about remembering the details of your workflow.

 > I was able to reconstruct the changes without too much difficulty.

That's good.  But people aren't always that lucky.

 > > It does, the same way that bzr or Mercurial does.[1]  I don't see
 > > why you would think otherwise.
 > Partly due to the following bug report which is near the start of the
 > git-merge man page:  "Warning: Running git merge with non-trivial
 > uncommitted changes is discouraged: while possible, it may leave you in a
 > state that is hard to back out of in the case of a conflict.".  I can't
 > imagine why the git maintainers don't fix this.

Fix what?  One can do it if one wants to.  It's usually not dangerous
because merge will abort if there are any local uncommitted changes in
a file that would be changed by the merge.  It's actually rather
useful in certain limited use cases, for example when I have a
different ignore file from upstream.  In Mercurial, I have a patch in
a queue that handles this but it's PITA to deal with.  (Note that
everybody's favorite blunted plastic scissors, aka Bazaar, has a
"merge --force" option to allow the user to make the choice.)

It is indeed a bad idea to do a lot of work without committing and
then merging.  But that's a trivial deduction from the general
theorem: it is a bad idea to do a lot of work without committing.

 > With git pull, if there are changes in the working directory, the merge
 > (i.e. merge from remote/master into master) part of the operation is
 > aborted before it starts, giving a message describing its refusal.  It
 > does this even when there are no conflicts to deal with.

No, it only does it if a locally changed file is to be updated by the
merge.  That is a conflict, because git has no way to bring you back
to the current state if you want to come back.  Git only knows how to
bring you back to a state that was committed.

 > Mercurial will complete hg pull regardless of any changes in its working
 > directory; in the case of conflicts it may leave several heads which
 > require merging.

Which is exactly what git does:

    b 22:00$ git pull
    remote: Counting objects: 3, done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 3 (delta 1), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /tmp/test/./a
       684eca7..d47c24c  master     -> origin/master  <<<< LOOK LOOK LOOK
    Updating 684eca7..d47c24c
    error: Your local changes to the following files would be overwritten
    by merge:
    Please, commit your changes or stash them before you can merge.

I think you're partly confused by the fact that what Mercurial calls
pull is what git calls fetch, and what git calls pull has no
equivalent in core Mercurial AFAIK (pull -u only updates on a fast

 > Part of the problem is that the git-merge man page doesn't say that
 > it messes with the working tree

What else would it do?  Merge tools have changed the working tree from
time immemorial.

What's different from traditional 3-way merge tools (that aren't part
of a VCS) is that git *also* creates a commit with more than one
parent (which is what is meant by joining development histories).  I
find it a PITA that Mercurial doesn't, but rather requires a separate
merge operation and then an explicit commit.

 > By contrast, hg merge is documented concisely and adequately as
 > "merge another revision into working directory".

Everybody hates git's documentation.  I thought you were complaining
about bugs in the program?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]