bzr update with local updates and commits does an unexpected merge

Bug #395514 reported by Marius Gedminas
This bug report is a duplicate of:  Bug #113809: update performs two merges. Edit Remove
24
This bug affects 4 people
Affects Status Importance Assigned to Milestone
Bazaar
Confirmed
High
Unassigned

Bug Description

Consider this sequence of shell commands:

mkdir bazaar-hates-me
cd bazaar-hates-me/
bzr init .
fortune > file1.txt
fortune > file2.txt
bzr add .
bzr ci -m "add files"
cd ..
bzr branch bazaar-hates-me/ bazaar-hates-me-again
cd bazaar-hates-me
fortune > file3.txt
bzr add file3.txt
bzr ci -m "add third file"
bzr bind ../bazaar-hates-me-again/
echo 'add a line' >> file2.txt
echo 'add a line' >> file3.txt
bzr st
bzr ci file2.txt -m "change old file"
# fails, says branches have diverged
bzr update
# RM file3.txt => file3.txt.THIS
# Contents conflict in file3.txt
# 1 conflicts encountered.
# RM file3.txt.THIS => file3.txt
# Text conflict in file3.txt
# Path conflict: file3.txt.THIS / file3.txt
# 2 conflicts encountered.
# Updated to revision 1.
# Your local commits will now show as pending merges with 'bzr status', and can be committed with 'bzr commit'.

This doesn't make any sense tp me:

  * either bzr bind pushes so the second branch should be the same as the first one
  * or bzr bind doesn't push in which case file3 hasn't made it to the second branch, so how can it conflict with itself?

Revision history for this message
Marius Gedminas (mgedmin) wrote :

Data loss warning: running 'bzr update' removes the revision that added file3.txt from the repository -> you can no longer see it in bzr log, for example.

Running 'bzr revert file3.txt' afterwards doesn't restore the file's contents to the commited version, as I'd expected, it removes the whole file. And since the history is also gone, I have lost data.

Revision history for this message
Marius Kruger (amanica) wrote :

what you described also happen if you do --local commits on a checkout.
bzr update basically does a merge which as you noted puts your local
commits as pending commits. so as soon as you commit, it would be visible with bzr log -n0

This is something we need to fix as there is now way that I know of that you can undo it ounce you are in this mess. There are similar bugs eg. #236724 and #307316

if you have local commits and local changes, bzr should refuse to operate and force you to commit first.
if there are no remote commits, it could possibly do a push.

Changed in bzr:
importance: Undecided → High
status: New → Confirmed
summary: - bzr push; bzr add; bzr ci; bzr bind; bzr ci -> weird conflict of a
- branch with itself
+ bzr update with local updates and commits does an unexpected merge
Revision history for this message
Matt Giuca (mgiuca) wrote :

I've been bitten by this recently. The problem is that bzr up is going to do uncommits on my repository.

There are two issues as I see it:
1. If there have been no commits on the remote branch since I branched, then I most likely do not want to merge. I just want to push my changes back to the remote. Once the merge has happened, there's no way for me to do that, except to simply re-commit the merge.
2. Once revisions have been committed, they should not be uncommitted (except if I run bzr uncommit). While it's not quite a destructive operation (as I still have the revisions around as an uncommitted merge), it's quite dangerous to take safely committed data and suddenly make it uncommitted changes. Running bzr revert (which I believe is a normal user's default response when such a mess happens) is highly destructive.

I believe the fix should be for bzr update to give an error message if it's going to do any uncommitting-and-merging. Then add an option such as --merge which gives update its current behaviour. The error message can say "Use bzr update --merge to merge your local commits with the remote branch. Warning: This will convert your local commits into a pending merge."

In the meantime, if you find yourself in this mess there's not much you can do, but there is a workaround (BACKUP your branch first). The old revisions are still in the repo, so if you do a revert (effectively losing all of your local commits), you can recover them.

First run "bzr unbind", then "bzr revert".

Run "bzr heads --dead-only", and you'll see the now-dead head of your branch. Then run "bzr pull -r REVID .", and give the rev-id of the head, which will pull all of the old commits back into your branch, and it should be as it was before running bzr up.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.