I'm new to Mercurial. I did hg status and I saw the files that changed since the last commit have M in front. I then tried hg update -C. Is there any way I can get back the version of the files with M before I did hg update -C? Or am I pretty much screwed? :( since hg update -C discards any changes since the last commit
Unfortunately, it's right there in hg help update:
options:
-C --clean discard uncommitted changes (no backup)
The proper workflow would have been to commit your outstanding changes (which would presumably create a new head) and merge your commit with the revisions you wanted to import.
If you don't like having to commit a half-baked set of changes, check out the shelve extension, which is designed exactly for this: It temporarily puts aside all or some of your uncommitted changes, allowing you to run hg operations before you bring them back again. (shelve is not distributed with mercurial, but I think tortoisehg may include it).
Well, let's take a look:
PS C:\dev> hg init foo
PS C:\dev> cd .\foo
PS C:\dev\foo> echo ":)" > file.txt
PS C:\dev\foo> hg add
adding file.txt
PS C:\dev\foo> hg com -m ":D"
PS C:\dev\foo> echo "DDDD" >> .\file.txt
PS C:\dev\foo> hg sta
M file.txt
PS C:\dev\foo> hg up -C
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
PS C:\dev\foo> hg sta
PS C:\dev\foo> dir
Directory: C:\dev\foo
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/14/2013 4:06 PM .hg
-a--- 5/14/2013 4:06 PM 10 file.txt
PS C:\dev\foo> type .\file.txt
:)
It's gone. :( Sorry for the bad news!
Some IDE's, like Intellij will separate from version control keep track of "Local History" I would check for that in a case like this.
Quite late answer for Jason, but may help the others.
We had the same problem and FOUND A SOLUTION here...
In brief:
type hg heads - you will see head of your changes is stil somewhere in the repository
copy ID of your head and type hg update <id_of_your_head>
Related
The problem here is that hg' workflow apparently leads in a circle:
hg pull, get another head
hg merge, get warned of outstanding
uncommitted changes
hg commit -m "pre merge commit", get message
saying nothing changed
go to 2 hg status, see output like the
following:
! #foo.py#
? junk.out
? junk2.out
If foo.py is in your list of .hg-ignore'd files try specifying it explicity on the command line when you commit.
e.g.
hg commit -m "commit message" ./#foo.py
edit: looking more closely at your error: the file has been deleted (! in the status list), but hg hasn't tracked the deletion. You need to tell hg about the deletion using:
hg rm -A ./foo.py
The -A / --after means record the removal after it actually occured
I accidentally did a "hg commit --amend" instead of just a commit. How can I roll back the commit to before the amend?
You can use hg reflog (from the journal extension) and hg reset <hash>.
hg reflog -v
should give something like:
<old-hash> -> <new-hash> <user> <timestamp> commit --amend <some-path>
if that is the amend you want to revert, just use:
hg reset <old-hash>
The commit will be reverted to what is previously was and the changes that were amended should now be uncommitted changes (check using hg status and hg diff).
If your version of Mercurial is new enough, I believe you should be able to use the hg unamend command from the uncommit extension that ships with Mercurial. This may require that obsolescence markers are enabled, I'm not sure.
Enable the uncommit extension, add this to your ~/.hgrc:
[extensions]
uncommit =
Actually run the unamend:
hg unamend
Find the latest saved backup in .hg/strip-backup directory
hg unbundle .hg/strip-backup/<latest backup>
Now you should have two heads - one with the amended commit, other one with two commits (first one - old commit before amending, second one caled: "temporary amend commit for (old commit hash)".
if you have histedit extension, you can do hg histedit on it in order to change it (e.g. select edit in order to achieve a state just before the commit, i.e. when you can see all changes using hg diff).
Don't forget to strip the old head.
It's 2022, and my attempts to use hg unamend have not worked. histedit is too clunky for my purposes, but the solution proposed by mariu52 elsewhere on this page can easily be adapted to work without histedit. It relies on the -k option of the strip subcommand.
In a nutshell:
Find the latest saved backup in the .hg/strip-backup/ directory
Run hg unbundle .hg/strip-backup/<latest backup> where <latest backup> signifies the full filename.
Run hg heads and note the rev number corresponding to the amendment.
Let's call this $AMENDREV; this is the rev number we will strip in the next step.
Run hg strip -k --rev $AMENDREV
Using the -k option in the strip command is critical.
WARNING: this procedure will in effect erase the memory of any add or remove commands
that were pending when the amend command was executed.
For example, in the transcript below, the hg add file2 command is effectively
forgotten after the strip command is executed.
For clarity, here's a transcript based on the above recipe.
$ mkdir tmp ; cd tmp
$ ls
$ echo 1 > file1
$ echo 2 > file2
$ hg init
$ ls
file1 file2
$ hg add file1
$ hg commit -m 'one file'
$ hg add file2
$ hg amend -m 'amendment'
saved backup bundle to /tmp/tmp/.hg/strip-backup/d332ee829c21-5a5f23b0-amend.hg
$ hg unbundle -u .hg/strip-backup/d332ee829c21-5a5f23b0-amend.hg
adding changesets
adding manifests
adding file changes
added 1 changesets with 0 changes to 1 files (+1 heads)
new changesets d332ee829c21 (1 drafts)
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
updated to "1a445f3252eb: amendment"
1 other heads for branch "default"
$ hg heads
1[tip]:-1 d332ee829c21 2022-11-09 01:55 -0500 peak
one file
0 1a445f3252eb 2022-11-09 01:55 -0500 peak
amendment
$ ls
file1 file2
$ hg strip -k -r 0
saved backup bundle to /tmp/tmp/.hg/strip-backup/1a445f3252eb-bfaab5ec-backup.hg
$ ls
file1 file2
$ hg list
r0: peak tip 2022-11-09 01:55 -0500
one file
file1
$
hg unamend part of Mercurial 4.5 (2018-02-01).
NOTE: This answer is now deprecated. See the answer from #Sorina Sandu instead.
See hg help commit, where it says:
The --amend flag can be used to amend the parent of the working
directory with a new commit that contains the changes in the parent in
addition to those currently reported by "hg status", if there are any.
The old commit is stored in a backup bundle in ".hg/strip-backup" (see
"hg help bundle" and "hg help unbundle" on how to restore it).
On commit to repository I have a hook defined in Mercurial:
[hooks]
precommit.exportDB=exportDB.bat
This creates/updates a SQL-dump from my database, which should be included in the commit.
BUT: although this works, the Sql is marked as new, but not part of the now commiting changeset.
How can I automatically include it so it gets into the set of changed files?
Hope this makes sense...
Thx
Reinhard
This'll sound crazy, but you can do it in two steps. First change your precommit hook to a pre-commit hook -- yup, both exist and they're different. Without the dash the commit has already started and some lock has been acquired. With the dash it happens before the commit starts and you can still hg add the new file.
On a unix like that total change would be:
[hooks]
pre-commit.exportDB=exportDB.sh && hg add resulting.sql
presumably there's something similar on Windows, or you could make the hg add the last line of the batch file.
P.S. Don't commit generated files. :)
Update:
I just tested this and it works as I suggested:
ry4an#four:~$ hg init reinhard
ry4an#four:~$ cd reinhard/
ry4an#four:~/reinhard$ vi .hg/hgrc
ry4an#four:~/reinhard$ cat .hg/hgrc
[hooks]
pre-commit = hg add otherfile
ry4an#four:~/reinhard$ echo text > afile
ry4an#four:~/reinhard$ echo more > otherfile
ry4an#four:~/reinhard$ hg add afile
ry4an#four:~/reinhard$ hg status
A afile
? otherfile
ry4an#four:~/reinhard$ hg commit -m 'message'
ry4an#four:~/reinhard$ hg status --all
C afile
C otherfile
Notice that before the commit only 'afile' is added and 'otherfile' is unknown, and after the commit both files are 'C' (meaning "Clean' -- they've been added and committed).
Is there a problem with Mercurial's guide for fixing case-folding collisions or is there a problem with the way I am implementing the solution.
The solution as provided on the Mercurial wiki is as follows:
hg clone -U repo repair
cd repair
hg debugsetparents <bad revision>
hg debugrebuildstate
At this point, Mercurial will think you have the bad revision checked
out and all the files are missing (status '!'). To fix the repo, we
simply have to do:
hg rm -A <file causing the collision>
Now hg st should show the troublesome file in state 'R' and all other
files in state '!'. Now we can check in our fix:
hg ci -m"fix case collision"
To get all our files back, we just check out again:
hg co tip
The problem files are: SomeFile.bash and Somefile.bash. I originally had Somefile.bash and I would like it to now be SomeFile.bash. Also to note, version 157 is happy, no collision, but version 158 is where I have introduced the collision. The head of the repository is currently at revision 160.
I have implemented this solution as follows:
hg clone -U my-repo-url repair
cd repair
hg debugsetparent 160
hg debugrebuildstate
hg status (reveals that everything is 'missing' (!))
hg rm -A Somefile.bash (responds that SomeFile.bash has been removed, notice case change)
hg ci -m "Fixed the collision... I hope."
hg co tip
hg update -C tip
According to the guide, this should have removed the case-folding collision and brought the rest of the missing files back, yet another hg status reveals that everything is still missing (!).
Edit: By appending that last command (the update) to the existing commands, I was able to recover the missing files which solved the remainder of the problem.
Note: I had to use the most recent 'problem' version for <bad revision> to fix this problem (that was 160 in my case).
Try
hg update -C tip
That should bring the files back. If not, try reverting everything:
hg revert -r tip -a
Is there a Mercurial command you can use after an hg pull to see a list of all files that will be need to be manually merged (ie: that have conflicts) when doing an hg merge?
hg resolve --list
From the documentation:
Merges with unresolved conflicts are often the result of non-interactive merging using the internal:merge configuration setting, or a command-line merge tool like diff3. The resolve command is used to manage the files involved in a merge, after hg merge has been run, and before hg commit is run (i.e. the working directory must have two parents).
Edit 5 January 2012:
(I received an up vote for this answer today so I revisited it. I discovered that I misunderstood the question.)
The question is "I have performed a pull from a remote repository and have not yet performed a merge. Can I see what conflicts will be created upon performing the merge?"
My answer above is clearly wrong. After reading through the linked documentation, I do not think there is a built-in method for doing this. However, there is a way to do it without ruining your working source tree.
Let's assume you have cloned repository A from some remote source to repository B on your local system, i.e. hg clone http://hg.example.com/A B. After doing so, you make changes to your local repository, B, that involve at least one commit. In the meantime, changes have been made to repository A so that when you do a pull you get a message indicated new changesets have been added and heads have been created.
At this point, you can do hg heads to list the two changesets that will be involved in a merge. From this information, you can issue a status command to list the differences between the heads. Assuming the revision numbers in your repository B, according to the heads list, are "1" and "2", then you can do hg status --rev 1:2 to see a list of the changes.
Of course, this doesn't really tell you if conflicts will occur when you do a merge. Since there isn't a command that will show you this, you will have to "preview" the merge by cloning to a new repository and doing the merge there. So, hg clone B C && cd C && hg merge. If you are satisfied with the result of this merge you can do hg com -m 'Merging complete' && hg push && cd ../ && rm -rf C.
It's a bit of a process, but it keeps your current source tree clean if the merge turns out to be a disaster. You might also find this description of working with public repositories helpful.
Unless I'm misreading it myself, the answers above don't seem to address the question that I think is being asked: I have two branches in my repository that I'd like to merge, and I want to know what conflicts will come up (e.g., before stepping through the conflict resolutions one-by-one.)
To do this, I would merge with the :merge3 tool (which tries to merge automatically, but leaves conflicts unresolved) and then use hg resolve --list — or just look at the output of merge command — to see the conflicts.
hg merge <otherbranch> --tool :merge3
hg resolve -l
If you didn't actually want to merge in the end (if you just want to see what would conflict) you can run hg update -C afterwards to undo the merge.
If you do want to finish the merge, you can run hg resolve <filepath> for each file, or just hg resolve --all to step through all that remain with conflicts, before you hg commit the merge changeset.
You can use the --rev option of hg stat with a pair of revisions to see what file differences exist between the two. See below for a slightly verbose but detailed example:
First we start by making a new repository:
[gkeramidas /tmp]$ hg init foo
[gkeramidas /tmp]$ cd foo
Then add a single file called foo.txt to the new repository:
[gkeramidas /tmp/foo]$ echo foo > foo.txt
[gkeramidas /tmp/foo]$ hg commit -Am 'add foo'
adding foo.txt
[gkeramidas /tmp/foo]$ hg glog
# 0[tip] b7ac7bd864b7 2011-01-30 18:11 -0800 gkeramidas
add foo
Now add a second file, called bar.txt as revision 1:
[gkeramidas /tmp/foo]$ echo bar > bar.txt
[gkeramidas /tmp/foo]$ hg commit -Am 'add bar'
adding bar.txt
Go back to revision 0, and add a third file, on a different head. This is done to simulate a pull from someone else who had cloned the same repository at its starting revision:
[gkeramidas /tmp/foo]$ hg up -C 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
[gkeramidas /tmp/foo]$ echo koko > koko.txt
[gkeramidas /tmp/foo]$ hg commit -Am 'add koko'
adding koko.txt
created new head
[gkeramidas /tmp/foo]$ hg glog
# 2[tip]:0 e5d80abdcb06 2011-01-30 18:12 -0800 gkeramidas
| add koko
|
| o 1 a2d0d0e66ce4 2011-01-30 18:12 -0800 gkeramidas
|/ add bar
|
o 0 b7ac7bd864b7 2011-01-30 18:11 -0800 gkeramidas
add foo
Now you can use hg stat to see what file differences exist between any pair of revisions, e.g. the changes from rev 0 to rev 1 added 'bar.txt' to the file list:
[gkeramidas /tmp/foo]$ hg stat --rev 0:1
A bar.txt
The changes from rev 0 to rev2 added 'koko.txt' to the file list:
[gkeramidas /tmp/foo]$ hg stat --rev 0:2
A koko.txt
But more interestingly, the changes from rev 1 to rev 2 involve two file manifest changes. (1) 'koko.txt' was added in rev 2, and (2) 'bar.txt' exists in rev 1 but is missing from rev 2, so it shows as a 'removed' file:
[gkeramidas /tmp/foo]$ hg stat --rev 1:2
A koko.txt
R bar.txt
I think hg status is what you are looking for.
You may want to read this chapter from Mercurial: The Definitive Guide
http://hgbook.red-bean.com/read/mercurial-in-daily-use.html