Why can't I merge when there are uncommitted outstanding changes?

341 views
Skip to first unread message

Aardwolf

unread,
Apr 22, 2010, 10:37:01 AM4/22/10
to merc...@selenic.com

I have some files I don't want to commit. I need to to a merge simply to be
able to push. But it can't merge, because it says "abort: outstanding
uncommitted changes (use 'hg status' to list changes)".

My uncommitted files have NOTHING to do with the merge, it are different
files.

Why can't I just merge?

This is really frustrating for me. Whenever I want to push my changes to the
"central" repository here, I have problems like this. I just want to have my
pushed files to be added linearly to the changes on the central repository.
The files I changed are usually different ones than other changes on the
central repository.

I don't understand why I need to go through such complex problems everytime
I just want to push my changes and at the same time keep a few uncommitted
changes.

What am I doing wrong that hg is so frustrating to me while everyone else
seems to love it?
--
View this message in context: http://old.nabble.com/Why-can%27t-I-merge-when-there-are-uncommitted-outstanding-changes--tp28329783p28329783.html
Sent from the Mercurial mailing list archive at Nabble.com.

_______________________________________________
Mercurial mailing list
Merc...@selenic.com
http://selenic.com/mailman/listinfo/mercurial

--
You received this message because you are subscribed to the Google Groups "mercurial" group.
To post to this group, send email to mercuria...@googlegroups.com.
To unsubscribe from this group, send email to mercurial_gene...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mercurial_general?hl=en.

Gabor Grothendieck

unread,
Apr 22, 2010, 10:43:53 AM4/22/10
to Aardwolf, merc...@selenic.com
This is not a direct answer to your question but you might want to look at:
http://www.selenic.com/pipermail/mercurial/2009-February/024162.html

Aardwolf

unread,
Apr 22, 2010, 10:49:55 AM4/22/10
to merc...@selenic.com

I'm sorry, but I tried this shelve extension, and it simply doesn't work for
me.

I've even made another post about it here. It doesn't simply allow "shelve",
"unshelve" then "shelve" again due to "abort: shelve data already exists"
error. It doesn't shelve files with an "A" if I try. When unshelving, no
matter how many times typing "hg unshelve", it always gives the message
"rolling back last transaction", whether or not it actually did something.
Sometimes it asks me to press "Y" many times in a row before it finally
shelves something. And sometimes unshelve doesn't even do anything at all
(it doesn't unshelve "M" files if there were "A" files that weren't shelved.

I need something where, without having to think (and having the ability to
make mistakes), I can "shelve", which means my data goes to the shelf, and
"unshelve", which means I get my data back, preferably without missing
pieces unless there was a conflict.

So no, the shelve extension doesn't make the problem lighter for me, it only
makes it harder.

---

But again, if I have uncommitted changes to file A, I have committed changes
to file B, and on the "central" repository there are changes to file C. How
hard can it be to automatically solve this by the tools? Isn't that what the
tools are for?

Why do I have to manually do so many tricks for that situation? I'm here to
write code, not someone who loves constantly playing with version control
systems. They're a very good tool to me to look up file histories (what did
other people do), give my changes to the rest, and get their changes, but
that's about it.
View this message in context: http://old.nabble.com/Why-can%27t-I-merge-when-there-are-uncommitted-outstanding-changes--tp28329783p28329955.html
Sent from the Mercurial mailing list archive at Nabble.com.

_______________________________________________
Mercurial mailing list
Merc...@selenic.com
http://selenic.com/mailman/listinfo/mercurial

Stephen Rasku

unread,
Apr 22, 2010, 10:59:03 AM4/22/10
to Aardwolf, merc...@selenic.com
On Thu, Apr 22, 2010 at 07:49, Aardwolf <toil...@gmail.com> wrote:

I'm sorry, but I tried this shelve extension, and it simply doesn't work for
me.
 
Can you do the following?:

1. clone the repo that needs the merge
2. do merge in clone
3. push merged clone (either to your repository or directly upstream)

Would that work for you?

...Stephen

Aardwolf

unread,
Apr 22, 2010, 11:06:10 AM4/22/10
to merc...@selenic.com

I've read about this here:
http://blogs.sun.com/tor/entry/mercurial_tip_checking_in_regularly

It's probably almost the only solution... But admit it, it's not simple
either. It requires manually pushing twice or making an sh script to do the
pushing twice for you, meaning no IntelliJ plugin will be able to do it
currently, making it less convenient in some cases.

Still, why do I encounter all these problems? Isn't it normal for a
developer to have various files he doesn't want to (currently) commit? I
know it is for me and most people here. There are so many reasons: partially
wanting to commit some of your work while keeping the rest local due to
still needing to work it out further. Local config file changes. Local test
code, .... Why is hg made so inconvenient for this case?

Also, what's the point of actually creating branches and merges in the hg
repository, just because someone else changed *different* files? The history
could be perfectly linear there...
> _______________________________________________
> Mercurial mailing list
> Merc...@selenic.com
> http://selenic.com/mailman/listinfo/mercurial
>
>

--
View this message in context: http://old.nabble.com/Why-can%27t-I-merge-when-there-are-uncommitted-outstanding-changes--tp28329783p28330165.html

Mads Kiilerich

unread,
Apr 22, 2010, 11:10:40 AM4/22/10
to Aardwolf, merc...@selenic.com
Aardwolf wrote, On 04/22/2010 04:49 PM:
> But again, if I have uncommitted changes to file A, I have committed changes
> to file B, and on the "central" repository there are changes to file C. How
> hard can it be to automatically solve this by the tools? Isn't that what the
> tools are for?
>
> Why do I have to manually do so many tricks for that situation? I'm here to
> write code, not someone who loves constantly playing with version control
> systems. They're a very good tool to me to look up file histories (what did
> other people do), give my changes to the rest, and get their changes, but
> that's about it.
>

You are trying to use a workflow that (often) works with CVS or SVN. And
because these VCSs enforces a linear history you actually have to use a
workflow like you describe. The disadvantage is that you don't know
exactly what you are committing, and you can't verify that the merge is
correct. And sometimes things go terribly wrong.

Mercurial always tracks whole repositories and doesn't encourage
workflows where you have many different changes in your working
directory at once. For example, when you merge then Mercurial will use
the working directory to resolve conflicts, and after the merge the
working directory contains exactly how the changeset will look when you
commit the merge. There can thus not be other changes in the working
directory.

You have to change your work-flow a bit if you want to use Mercurial.

In your case I would probably wait with the merge until I am ready to
commit my local changes, commit them, and then merge and commit the
merge. If the merge goes wrong it can be discarded before commit and
done again.

If I need the other changes in order to continue I would create another
clone / working directory, pull the changesets that has to be merged
into it, do the merge and commit, and pull the result into the first
working directory and update. But note that the update with pending
changes in the working directory is slightly risky if you end up with
conflicts and can't resolve them correctly. Merging tracked revisions is
more reliable.

In the trivial case where distinct files are changed then Mercurials
work-flow is a bit overkill. But it is 100% reliable and works in all cases.

(And I suggest that you forget about extensions until you are familiar
with these work-flows.)

/Mads

Jason Harris

unread,
Apr 22, 2010, 11:20:37 AM4/22/10
to Mads Kiilerich, Aardwolf, mercurial-devel
Also some people when they are familiar with Mercurial use a few more advanced tools to clean up their revision history a bit before *pushing* Eg rebase, hist-edit, or mercurial queues.

For me I just commit with reckless abandon lots of the time without really thinking in huge detail about my commits (With CVS I used to have triple check that I didn't make some stupid goof that would be enshrined making me look like an idiot for all time.) Now I just commit, commit, commit, and then before I push I clean things up a bit if necessary. This is a *much* *much* faster workflow for me. There is really no reason not to commit before doing other changes. Committing makes a "unit" package of the parts. This can then be moved around, reordered, etc if you need to.

Actually I find that in the end I don't always move things around. Its more common for me to do lots of commits and then occasionally rebase or reorder stuff before pushing.

(Admittedly I might find things frustrating if I couldn't occasional rewrite history before doing a push...)

Cheers,
Jas

Aardwolf

unread,
Apr 22, 2010, 11:34:45 AM4/22/10
to merc...@selenic.com

I'm already using rebase, because, unless there is actually a *reason* to
merge (that is, there is a change by two people in the same file), I don't
like seeing two branches merging in the history, and also don't like seeing
my name on files that I didn't actually type code in in the history (when
merging, then other peoples files are suddenly somehow related to me...).
But rebase has the exact same problem as merge: doesn't want to if there are
uncommitted changes.

I have no problems changing my workflow for mercurial, I even want to find
the right workflow :)

But giving up the ability to have uncommitted changes while doing other
things is hard. I mean, sometimes there just is that settings file that I
want to keep my uncommitted adjustement in forever, and sometimes I just
want to push to the central server to have a backup of something, or because
something is needed there "right now", even when I still need to write a lot
of code in other things.

And working with multiple local repositories seems to solve a lot of things,
but it's also a bit inconvenient at first sight. A reliable shelve tool
would be best I think, someone mentioned the attic extension elsewhere, I'll
give that one a try and hopefully that solves a lot of things for me.

The first version control system I worked with was SVN. Then later I had
unfortunately to work with CVS, and I liked SVN a lot better. Then now we
switched to HG and I hoped it'd be better than SVN, but I appear to have a
very hard time adjusting, simply because I still can't grasp while working
in different files than other people could even require a merge at all or
give problems with my working directory at all. Technically there seems to
be no reason for problems here. And SVN handled this always exactly as I
would expect.
View this message in context: http://old.nabble.com/Why-can%27t-I-merge-when-there-are-uncommitted-outstanding-changes--tp28329783p28330593.html
Sent from the Mercurial mailing list archive at Nabble.com.

Stephen Rasku

unread,
Apr 22, 2010, 11:51:21 AM4/22/10
to Aardwolf, merc...@selenic.com
On Thu, Apr 22, 2010 at 08:34, Aardwolf <toil...@gmail.com> wrote:

The first version control system I worked with was SVN. Then later I had
unfortunately to work with CVS, and I liked SVN a lot better. Then now we
switched to HG and I hoped it'd be better than SVN, but I appear to have a
very hard time adjusting, simply because I still can't grasp while working
in different files than other people could even require a merge at all or
give problems with my working directory at all. Technically there seems to
be no reason for problems here. And SVN handled this always exactly as I
would expect.

This gets a bit of getting used to but in CVS (maybe with SVN; I am not so familiar with it) it's possible for one developer  to commit file A and another to developer to commit to file B.  They could both then test with their own changes locally without seeing the others changes but it's possible that interactions between the two files could create bugs (e.g. if one developer is fixing bug in a function and another is fixing it in the caller).

Mercurial has a concept of changesets.  If developers only test with checked in code you can be guaranteed that you have the exact same code that the other developer used to do their tests.  This is not the case with CVS as I explained above.  Of course, if you are testing with local uncommited changes this is not true.

If you haven't already, you should take a look at Joel Spolsky's site on Mercurial <http://hginit.com/>.  It gives a great introduction on Mercurial, describes the philosophy of Mercurial, and how to resolve some of the expectations you might have coming from CVCS like CVS or Subversion.

...Stephen

Paul Boddie

unread,
Apr 22, 2010, 11:53:41 AM4/22/10
to Mads Kiilerich, Aardwolf, merc...@selenic.com
Mads Kiilerich wrote:
> Mercurial always tracks whole repositories and doesn't encourage
> workflows where you have many different changes in your working
> directory at once. For example, when you merge then Mercurial will use
> the working directory to resolve conflicts, and after the merge the
> working directory contains exactly how the changeset will look when
> you commit the merge. There can thus not be other changes in the
> working directory.

This is a good explanation. I've tried to add a suitable FAQ (since I'm
sure this affects everyone at some point), but the wording is arguably a
bit clumsy. Feel free to improve it!

http://mercurial.selenic.com/wiki/FAQ/CommonProblems#Why_won.27t_Mercurial_let_me_merge_because_I_have_uncommitted_changes.3F

Paul

Kastner Masilko, Friedrich

unread,
Apr 22, 2010, 11:48:20 AM4/22/10
to merc...@selenic.com
In your case I'd propose a setup using a second working-copy (to do the merge/rebase/whatnot work) by means of using the share extension. If you have your project in e.g. /path/to/project , do "hg share /path/to/project /path/to/workplace".

You will then have all repository elements shared between the two directories, but separate working-copies. You could do all your development work in /project/, but repo-maintenance in /workplace/. You'd have to "hg up" your /project/-working-copy to revisions created by merge/rebase in /workplace/ , though, but this is just like SVN, then.

Regards,
Fritz

Development Software Systems
Festo Gesellschaft m.b.H.
Linzer Strasse 227
Austria - 1140 Wien

Firmenbuch Wien
FN 38435y

Tel: +43(1)91075-198
Fax: +43(1)91075-282
www.festo.at

Der Inhalt dieses E-Mails ist ausschliesslich fuer den bezeichneten Adressaten bestimmt. Jede Form der Kenntnisnahme,
Veroeffentlichung, Vervielfaeltigung oder Weitergabe des Inhalts dieses E-Mails durch unberechtigte Dritte ist unzulaessig. Wir
bitten Sie, sich mit dem Absender des E-Mails in Verbindung zu setzen, falls Sie nicht der Adressat dieses E-Mails sind und das
Material von Ihrem Computer zu loeschen.

This e-mail and any attachments are confidential and intended solely for the addressee. The perusal, publication, copying or
dissemination of the contents of this e-mail by unauthorised third parties is prohibited. If you are not the intended recipient of this
e-mail, please delete it and immediately notify the sender.

Chad Dombrova

unread,
Apr 22, 2010, 11:59:08 AM4/22/10
to Kastner Masilko, Friedrich, merc...@selenic.com

In your case I'd propose a setup using a second working-copy (to do the merge/rebase/whatnot work) by means of using the share extension. If you have your project in e.g. /path/to/project , do "hg share /path/to/project /path/to/workplace".

just keep in mind that you can't share a repository that has subrepos.  it causes hg to error.


Mike Meyer

unread,
Apr 22, 2010, 12:28:43 PM4/22/10
to Aardwolf, merc...@selenic.com
On Thu, 22 Apr 2010 08:06:10 -0700 (PDT)
Aardwolf <toil...@gmail.com> wrote:

> Still, why do I encounter all these problems? Isn't it normal for a
> developer to have various files he doesn't want to (currently) commit? I
> know it is for me and most people here. There are so many reasons: partially
> wanting to commit some of your work while keeping the rest local due to
> still needing to work it out further. Local config file changes. Local test
> code, .... Why is hg made so inconvenient for this case?

Yes, it's normal. But I always treat it as a bad habit, and try and
break my users of it - even if we're using SVN or Perforce. Actually,
*especially* if we're using SVN or Perforce, where committing the
files creates a backup on a different disk/machine.

While the trunk may (or may not, depending on policy) need to always
be production quality, that's no reason to deprive yourself of the
facilities of a VCS for non-trivial changes. Branches (or repo clones
in hg) are cheap, so you should feel free to create them for anything
that's going to take more than a day or so to complete. That way you
can check in code that's not fully functional, but has otherwise
reached a milestone, or just because it's the end of the day, or
whatever - without breaking the trunk. Those also make good times to
merge appropriate changes from the trunk.

As for other things: config files shouldn't be in the repo, and tests
should generally be committed along with the code they test - or on a
different branch if they're not ready for the trunk yet.

> Also, what's the point of actually creating branches and merges in the hg
> repository, just because someone else changed *different* files? The history
> could be perfectly linear there...

I, on the other hand, don't understand this desire for a history
that's perfectly linear - especially when said history is
revisionist. But that also seems to be a common desire among DVCS
users...

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Matt Mackall

unread,
Apr 22, 2010, 1:16:10 PM4/22/10
to Aardwolf, merc...@selenic.com
On Thu, 2010-04-22 at 07:49 -0700, Aardwolf wrote:
> I'm sorry, but I tried this shelve extension, and it simply doesn't work for
> me.

I really really wish people wouldn't reach for extensions as the first
line of advice. It only adds more complexity to existing confusion.

The "shelve" operation is conceptually no more than:

hg diff > somefile # save local changes
hg revert -a # nuke 'em

And "unshelve" is simply:

hg import --no-commit somefile

I do this occasionally, but I actually rarely find "shelving" necessary.
And I've never needed the shelve extension. For the first couple years
of Mercurial development, I didn't use mq either, so I always cringe
when people advise beginners to use it. None of the extensions are
essential, folks.

ps: some folks might want diff -g.

--
http://selenic.com : development and support for Mercurial and Linux

Cameron Simpson

unread,
Apr 22, 2010, 8:53:33 PM4/22/10
to Aardwolf, merc...@selenic.com
On 22Apr2010 08:34, Aardwolf <toil...@gmail.com> wrote:
| Jason Harris-8 wrote:
[...]
| > For me I just commit with reckless abandon lots of the time without really
| > thinking in huge detail about my commits [...] Now I just commit, commit, commit,
| > and then before I push I clean things up a bit if necessary. This is a
| > *much* *much* faster workflow for me. There is really no reason not to
| > commit before doing other changes. Committing makes a "unit" package of
| > the parts. This can then be moved around, reordered, etc if you need to.
|
| I'm already using rebase, because, unless there is actually a *reason* to
| merge (that is, there is a change by two people in the same file), I don't
| like seeing two branches merging in the history, and also don't like seeing
| my name on files that I didn't actually type code in in the history (when
| merging, then other peoples files are suddenly somehow related to me...).
| But rebase has the exact same problem as merge: doesn't want to if there are
| uncommitted changes.

I think Jason's point is that you might consider committing your outstanding
changes, merging, then moving your previously-outstanding changes off to the
side before you push. That way you have a little mini-branch with your
outstanding changes, which after all are exactly that in a sense.
--
Cameron Simpson <c...@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

library, n., a place with a large number of people, a slightly larger number
of books, and a very small number of photocopiers, of which at any
given time at least 50% will be out of order.

Giorgos Keramidas

unread,
Apr 23, 2010, 6:34:39 AM4/23/10
to Aardwolf, merc...@selenic.com
On Thu, 22 Apr 2010 08:34:45 -0700 (PDT), Aardwolf <toil...@gmail.com> wrote:
> The first version control system I worked with was SVN. Then later I
> had unfortunately to work with CVS, and I liked SVN a lot better. Then
> now we switched to HG and I hoped it'd be better than SVN, but I
> appear to have a very hard time adjusting, simply because I still
> can't grasp while working in different files than other people could
> even require a merge at all or give problems with my working directory
> at all. Technically there seems to be no reason for problems here. And
> SVN handled this always exactly as I would expect.

There usually *is* a reason but it won't bite you until the most
inopportune moment. The reason why you have to merge even if you made
changes to different files is simple: Mercurial does not do *semantic*
merges. It does not know what the contents of the files _mean_ for
everyone and anyone who will ever read them.

Files tracked under Mercurial are very often source code. Every file
has interactions with parts of, or it uses the interfaces provided by
some other files. This means that if you use a model of history like
the one used by Subversion you may start with a history like this:

--------- [30] --- [31] --- [32]

When you check out revision 32 in your working directory you run some
tests and you see that two files don't work together very well: one of
the functions from lib/libfoo/foo_open.c fails when called from another
library at lib/libbar/bar_init.c.

So you run the tests a few more times, and you finally come up with a
patch that sits on top of revision [32] and appears to fix the problem:

State of the files | Local working-copy
in the remote | changes
repository |
|
--------- [30] --- [31] --- [32] ------- [patch 1]
|

You run the tests once more and you see that it all works. So you
prepare to svn commit your [patch 1] state. But someone else has
managed to commit his own stuff before you, so the repository really now
looks like this:


State of the files | Local working-copy
in the remote | changes
repository |
|
--------- [30] --- [31] --- [32] --- [33] ------ [patch 1]
* |

Now if there are no conflicts at the _file-level_ svn will permit your
patch to be committed. But does this new state of the entire repository
work? What if the changes in revision [33] affected other parts of the
lib/libbar/ library and introduced even *more* instances of the bogus
interface you tried to fix in [patch 1]? What if a _third_ person
committed version [34] while you were merging your patch on top of [33]?

You will never know, until you check out a full and clean copy of the
_entire_ branch again, and run the tests once more. By then the commit
you just pushed to the repository may have been pulled into the working
copies of any number of people. So you just committed something that
gives you the impression of having fixed the bug, but the important
detail is that you don't really know *yet*.

What you just did with Subversion is a bit of a juggling operation
between four different states of the repository:

1. The original, unpatched revision [32] code

2. Your patched version of revision [32]

3. The original, unpatched revision [33] somebody else committed

4. The merged patch of yours on top of revision [33]

You started from state (1), and patched your source to state (2). The
tests seemed to pass for state (2), so you committed on top of state (3)
creating a final state (4) in the repository. The most important detail
is, however, that you are *allowed* to commit files in the repository
that create a 'mix and match' state between these four different copies
of the source tree _without_ being able to test this version well in
advance of the commit itself.

You have to race other committers between "svn update" and "svn commit"
for a consistent state of the source tree. If nobody else commits even
a trivial change between your own "svn update" and "svn commit"
commands, then all is good. If they do, you just created a "mixed copy"
of the source tree files that has *never* been tested as a consistent
set of files before hitting the repository.

The downsides of this are:

* If you are asked to reason about the state of the repository before
and after your own commit it is a bit hard or even impossible to do
with svn (it depends on who else got a chance to push their own
stuff between the time you checked out the source and the time you
pushed your own commit).

* You are literally *forced* in some cases to push changes to the
repository that you have *not* tested as a consistent, coherent
whole.

Now having said that there are many projects who find subversion useful
and can mostly get away with these two down-sides. The world is not
going to end if you push a set of changes that update the documentation
of something without testing that it matches the actual code. The world
is not going to end if you break the build for half an hour either.

But it's still annoying...
Reply all
Reply to author
Forward
0 new messages