As of 2016-02-26, there will be no more posts for this blog. s/blog/pba/
Showing posts with label Mercurial. Show all posts

We all love git commit --amend [-a[m "blah"]] for at least one reason, you can edit the original commit message without needing to manually copy original commit message first. Unlike hg rollback-and-hg commit, which requires you to backup the commit message on your own.

If the commit message is a one-liner, I usually use history search to re-commit with previous commit command and edit the message if required. But sometimes, the commit message has more than one line, although it doesnt take long to copy the original message, but it still takes time.

I felt there may be a tip for an easier solution, so I searched for one, then I gasped You gotta be kidding me! when I saw the solution, a really simple solution.

Since Mercurial 2.2, which was released on 2012-05-01, you can do exactly the same as you do with Git, that is hg ci --amend. Basically, this new option has been around for 1 year and almost 4 months and I just learned about its existence.

It means I basically had been doing re-committing or editing very inefficiently for a long time. If I want to defend myself, than my excuse would be this:

 % sudo genlop mercurial
 * dev-util/mercurial

[snip]
     Tue May  8 08:59:24 2012 >>> dev-vcs/mercurial-2.1.1
     Mon Feb  4 02:04:34 2013 >>> dev-vcs/mercurial-2.4.2

Only six months, just only.

Admittedly, I dont read changelog as you can already tell. At least not until I encounter a bug. This lesson teaches me, maybe I should read changelog more often. Well, still not gonna happen, we aint got no time for that!

I had created a head in a Mercurial (Hg) repository, at the time, I thought that was a good idea to keep it around, even there would be no more commits on top of that head. However, its not, because it always showed up in hg heads.

1Solution

I would like to merge but not to keep changes of that head. A solution is to use hg debugsetparents, the basic process is like:

$ hg debugsetparents . <REV-OF-ANOTHER-HEAD>
$ hg commit -m Drop <REV-OF-ANOTHER-HEAD>

The result will look like a merge in hg log --graph, but we do not use merge command but a commit command. For this new commit, it will have two parents, one is the commit of that head, another is working copys original parent.

Although I dont know the scene behind, it should be essentially a merge because of two parents. We set an additional parent and commit like a regular commit.

2Walkthrough

If you used to (and still) use Subversion, you may not be able to get rid of your muscle memory when you need to check the status of a Git repository. For me, one out of two times, I would type:
git st
It is hardwired in me and Mercurial (Hg) has st as a shortcut, so it gets harder to remember to type the full command when I am using Git.

Git has alias configuration to customize the environment, check out man git-config. You can create a global (meaning for all repositories) alias for status command by typing:
git config --global --add alias.st status
It adds a new entry to global Git configuration file ~/.gitconfig:
[alias]
   st = status
You can manually edit the file if you want. Instead, you can create local alias command which only be used by single repository and configuration is stored in that repository only. But for status command alias, global availability suits better.

ci is a good one to be added for commit command, the second common command for me to get error message from Git, but that's history, too.

I got the warning message (not error) when I tried to add a file with colon (:) in its filename to a Hg repo. The repo is basically private, I don't intent to publish it to public, but I think it's still worth to resolve the issue even I don't use Windows.

There are some restrictions on file naming on Windows/DOS file systems. The message was added by a patch and there was a bug report related to this issue. I don't know what will happen if you try to clone such repo, but I am guessing files with illegal names will not be updated into working directory.

From that bug report, there is no remapping to work around, so it is best not to use anything may cause issues on different file systems. By default, it's only a warning, you can still commit the addition action.

If you don't want to see such warning, you can update your hgrc by adding:
[ui]
portablefilenames = ignore
which will suppress the warning message. If you want to stop the actions may cause issues, then gives it abort. You can read more about this configuration in man 5 hgrc.

If you have used GitHub, you must have already been familiar with gh-pages branch.

I don't like have different code base from the pages branch, so in my projects, master == gh-pages, and many of projects are doing the same. If you have documents like library reference which is generated by source, then you probably will use different base.

For a very long time, I had to do with these commands as follow in order to update that branch:
git checkout gh-pages
git pull . gh-pages
git push
git checkout master

It was just plain silly of me. I did google for it, but not RTFM, I didn't get any useful results, probably used wrong keywords. I finally found the correct answer with correct search keywords, here is the answer:
git push origin master:gh-pages

Here is from manpage git-push:
<refspec>...
    The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>, followed by a colon :,
    followed by the destination ref <dst>. It is used to specify with what <src> object the <dst> ref in the remote
    repository is to be updated.
    [...]
    The <dst> tells which ref on the remote side is updated with this push. Arbitrary expressions cannot be used here, an
    actual ref must be named. If :<dst> is omitted, the same ref as <src> will be updated.

Well, it's all in the manual and I was actually using a shorthand by omitting the <dst>. It's good to know.

So what if you try to omit <src> part? (I am glad I already know about this. Hehe, I am bad!)
git push origin :remote-branch

I created a project on github for mirroring my project on Google Code. I am new to git, so maybe there is a better way to do this.

First clone the Subversion repository and push to the Git:
git svn clone https://foo.googlecode.com/svn/ git-foo
cd git-foo
git remote add git-foo [email protected]:username/foo.git
git push git-foo master
After committing in the Subversion repository, run
cd /path/to/git-foo
git svn fetch
git svn rebase
git push git-foo master