Create a hg bookmark after committing a changeset - version-control

I cloned a Mercurial repo and made some changes in the checked out code. I then grabbed those changes (7 files) and committed them with hg commit but without having created a bookmark first.
This is the output of my hg summary command:
parent: 8172:b39efc1322fe tip
Made some changes in my feature
branch: default
commit: 7 modified
update: 2 new changesets, 3 branch heads (merge)
phases: 3 draft
These changes won't be ready to be pushed for at least another week, so I want to switch to a new bookmark and work on other parts of the code.
The problem is that I realized that I had made a commit without being in a bookmark, so I'm afraid that after switching to a new bookmark my committed changes could be lost.
Is there an easy way to move these committed changes into a new bookmark?

There is no need to be afraid at all: mercurial won't forget anything you committed unless you explicitly do both: enable history editing extensions and willingly use them in a way that you actually remove one or more changesets.
Mercurial is not git and mercurial does never forget or garbage-collect a changeset when it is not currently checked out and has no name (bookmark) attached to it.
You can show you all your heads using hg heads. And you can always create new bookmarks, attached to an arbitrary changeset by hg bookmark --rev XXX MyBookmark where XXX is the changesetID to which you want to attach the bookmark.

I'm afraid that after switching to a new bookmark my committed changes could be lost.
How can you imagine this? OMFG, you committed your changes to repository (your clone), you have this changeset (8172:b39efc1322fe) in it. When|if you'll svn up to another node, you'll just change parent of your Working Directory, on pull you'll get "2 new changeset" and, as result "3 branch heads" - 2 new changesets + your commit 8172, and this b39efc1322fe will be always one of heads, even you'll up and work in another.
If you are afraid to forget it (how??? really), you can post-fact bookmark this (committed) changeset with hg bookmark -r b39efc1322fe $WIP && hg commit -m "Bookmarked my work" in order to hg up $WIP when it will be time to continue this chunk of changes

Related

Created a named branch from the wrong parent

I am stuck in a scenario in which I have created a branch on Mercurial Workbench from a wrong parent branch. In other words I had to create a feature branch from parent : xxx and I have created it from parent : yyy.
Please note that I have also committed the changes, Is there any way I can either redirect my feature branch to xxx or I can delete the branch and re-create it with the same name (please note that having the same name is important) but this time I can create it from xxx.
I have exported the patches of my commits so after creating a branch even if my commits are lost I can import the patches again.
If you needed to change the branch name you would want hg graft (see Graft vs. Transplant). But since you don't want to change the name, you only want to redo the base of the commits, you want hg rebase.
See Hg: How to do a rebase like git's rebase and also In Mercurial what's the difference between hg graft and hg rebase. Note that rebase is an extension, but is a bundled one: you merely need to enable it.

How do I revert all files to a previous commit using EGit?

I am using EGit 2.2.0.20-1212191850-r with GitHub. All of my local files are committed and pushed. There is only the master branch. I would like to permanently revert all of my files to a previous commit (not HEAD~1). How do I do it?
Here's what I have tried:
I opened the History pane, where I see all past commits.
I right-clicked on the earlier commit and selected Reset > Hard.
I see the old version. I try committing the old version but none of the changed files show up in the Commit Changes window, even if I explicitly add them to the index.
I also tried Checkout in step 2, with the same result.
Eclipse git checkout (aka, revert) is not relevant, since it is just about reverting to HEAD, not an earlier commit.
What I'd really like to do is create a new branch from the earlier commit, but I'll settle for reverting.
If you already pushed the commits, it is generally recommended to revert the commits. The reason for that is that revert will add new commits to the history instead of replacing the history, which makes it possible for other people to just pull instead of having to rebase on the replaced history.
So in the History view, select the newest commit you want to undo, open the context menu and select "Revert". Repeat for the parent commits. When you're done, push the result.
Also note that "git checkout" and "git revert" are different things, "git revert" creates a new commit that undos the changes of a previous commit. "git checkout" on the other hand changes the working directory or current branch to a commit. You may be confused because "svn revert" does what "git checkout" does, not "git revert".

Does EGit "Revert Commit" permanently delete the original commit?

I'm still learning Git's workflow for doing things, and realized that I was accidentally in the wrong working branch when I committed some files. So using EGit, I listed the commit history and selected Revert Commit from the context menu for a couple of commits.
I have since realized that I wanted those commits, but cannot find the original commits anywhere. It seems as though the original commits were all but deleted. Even doing a full log listing on the entire git repo does not show the original commit or the revert commits.
From my understanding of the EGit docs, revert commit was just supposed to "undo" the changes by creating a new commit ontop of the old one, undoing what it had done. However, it would appear that it actually deleted my original commits.
Am I toast? Did I permanently lose those changes? I'm running Eclipse 3.7 with EGit 2.1.0.20120919.
git revert, as you said, doesn't delete the commits. It only creates a new commit undoing the changes of a certain commit passed to it. So, the original commit is still in the repository. Listing the commits with git log should show the original commit and the commit that undo what the original commit does.
With that, to recover the original content of the commit, you can revert the revert commit or change your repository status to the commit before the revert with git reset --hard hash where hash represents the hash of the commit before the commits that represents your git revert.
Your best bet is to leave eclipse and egit for a while and use the commandline.
There is a tool called git reflog that can show you much more than git log. I suggest you give that a try to see what you have done to the repository.

Use case for private changes

Supposing I have following scenario: I cloned some open-source project, say from URL X. Now I have local clone of it. I made some changes to local clone to try things out and commited them locally. Now what I want is following:
I want to get update from the open-source project X. Just get all its latest code, without my changes at all. But I want my changes to live somewhere in tag in history so I can get them later. And I don't want to separate clone for this, want it all in my one repo.
For now I did following:
Tag my changes with hg tag
Pull & merge latest code from URL X
Revert repository to latest revision of URL X
But I feel this isn't good way and it's roundabout. I think there's better way. Could you please suggest?
Instead of tags, I would use a bookmark. If you use Mercurial 1.8 or later, you already have the bookmark functionality built-in. Otherwise, you first have enable the extension by putting the following in your ~/.hgrc file:
[extensions]
bookmarks =
[bookmarks]
track.current = True
Now get the clone of your project:
hg clone http://bitbucket.org/user/X
cd X
and hack away:
# edit, edit, edit...
hg commit -m 'Great new feature!'
Now put a bookmark on this changeset
hg bookmark mywork
This is like a tag, but the advantage of a bookmark is that is moves along when you make new commits. This is just like when you're reading a book and move the bookmark along with you. When the bookmark is created, you can do
hg update mywork
to get back to the bookmarked changeset.
When there has been changes made in the upstream repository, then you pull and merge them into your own branch:
hg update mywork # if necessary
hg pull
hg merge
hg commit -m 'Merged new upstream changes.'
The bookmark will have moved forward and is now pointing to the merge changeset you just created. If you want to update to the version in X, then
hg update --rev -2
will do it after you pulled in changes -- this updates to the old tip changeset from before the merge, which was the tip of X.

Merge two checkouts in bazaar

I'm just starting out with bazaar, and I've found that the checkout feature is the most useful for the way I work - namely I can c/o from a "master copy", do some development and then commit my changes in the new directory. This then updates the "master copy".
But what if I'm working on (eg) two projects, changing different portions of code? Say:
~/master - master copy
bzr co master ./gui
bzr co master ./engine
So I'm doing gui-related stuff in the ./gui directory and under-the-hood stuff in ./engine. How should I commit my changes? If I commit gui first, then engine, I guess any conflicts will be flagged in engine?
Is there a way to merge gui and engine, and then do just one commit to the master copy?
To make things a little more complicated, how about if I do this:
bzr branch gui ./mouse
Now I perhaps I've been working on mouse, but also on gui. If I want to merge the code from gui AND mouse, and then commit to master, what is the best way to manage this? Or indeed, if I also:
bzr branch gui ./keyboard
If I've changed altered gui, keyboard and mouse, should I hierarchically merge - ie mouse+keyboard, then merge this with gui, then commit gui to master?
I hope it is clear what I'm trying to achieve! Thanks in advance for your time.
If you have two checkouts, any time you commit changes to one, you will first have to pull down any changes from the other one, potentially having to resolve conflicts at each step. This is generally a good idea, since it's easier to resolve conflicts over time and make sure your code doesn't diverge too much.
However, it sounds like you want to have separate developers working on "gui" and "engine", or you just want to save your conflict resolution till development on both branches has completed. In this case, you should probably create them as independent branches with "bzr branch". Each branch can use local commits and not worry about conflicts with each other. Then when it comes time to merge you can do it one of 3 ways, all of which get the same end result:
1. Merge one branch into the other, then push it up to master:
cd gui
bzr merge ../engine
# manually fix any conflicts
bzr commit
bzr push #back up to main
The downside to the above method is that your "gui" branch now has the "engine" changes in it. Which is fine if you're going to throw away both branches once they're pushed back into the mainline. But if you want to keep the branches longer, you can:
2. Merge into the mainline:
cd master
bzr merge ../gui
bzr commit
bzr merge ../engine
# manually fix conflicts
bzr commit
This has the upside that you still have "gui" and "engine" as separate branches, but you've had to commit one to master before you were sure that they would both work together. So you really probably want to:
3. Create a merge branch:
bzr branch ~/master gui-engine-merge
cd gui-engine-merge
bzr merge ../gui
bzr commit
bzr merge ../engine
# manually fix conflicts
bzr commit
bzr push ~/master
# since this branch was only for merging, you don't need it anymore:
cd ..
rm -r gui-engine-merge
Yes, bzr should prevent you from checking in changes from the engine repo if it detects conflicts. Normally, you first do "bzr up" just prior to check-in and then make sure your stuff plays nice with others.
As for the second part of your question, dealing with mouse/keyboard branches, this is how I would normally do it. Simply cd into the gui dir, and then do:
bzr merge ../mouse
After merging the changes, you can then commit from the gui directory and it will send the changeset to the "master" directory.
Note that I'm hardly a bzr expert, but this is the way I've been dealing with SVN repos.