Mercurial over Git
jonchu.posterous.com
jonchu.posterous.com
'git branch <branchname> [start-point]' creates a new branch....
Maybe he is referring to the fact that git branch wont change change branches? You have to use git checkout to actually switch branches.
"Not only is documentation for some important features sparse, the documentation that does exist is rarely ever of the best quality."
I am curious what specifically he was referring to. The docs on git-scm are pretty extensive. Between the docs, books, cheatsheets, videos there is a ton out there. Even the man pages include example usage where many man pages for command line tools do not.
Something I can't help but ponder is that in switching to the second system they already had a grasp of some dvc concepts making it easier and if trying git second would have been easier.
$ cat git-create-branch #!/bin/sh
if [ $# -ne 1 ]; then echo 1>&2 Usage: $0 branch_name exit 127 fi
branch_name="$1" git push origin origin:refs/heads/${branch_name} git fetch origin git checkout --track -b ${branch_name} origin/${branch_name} git pull
First of all,
git push origin origin:refs/heads/${branch_name}
is totally unnecessary when creating a new branch.I see that there are remote branches you want to track. It's simple, no need for a script. Just make sure you are synced with the current version of the repo you are using (using `git pull`). Then:
git checkout --track -b bugfix origin/bugfix
Easy as pie. I even have an alias set when I want to do this, so I just call git cot bugfix origin/bugfix
To create a new branch locally (that doesn't track a remote), just call git checkout -b new-feature
Note: When using `git pull`, `git fetch` doesn't need to be called. Pulling changes will fetch them for you automatically.Everyone comes to the plate with different experiences/expectations. You can't hope to satisfy everyone.
hg branch new-feature
If you want it to branch from a different changeset than the one you're on, then: hg update deadbeef
hg branch new-feature
No flags, no orgin/newfeature (what does that even mean?), just the commands describing exactly what you're doing.git checkout -b new-feature
The only diff is -b, which is fine to me because it makes it clear that you are doing two things. You don't need the origin/newfeature stuff for the common case. I'm assuming this is what 'hg branch new-feature' is doing. How do you create a branch and not switch to it?
hg branch new-feature
hg update default
But why would you not want to switch to a branch you just created? Why create the branch if you're not going to work on it?'hg branch foo' just marks the working directory as branch foo. The 'hg update default' would then update back to the default branch and mark the working directory as being on 'default'.
To really just create a new branch you do: 'hg branch foo; hg commit -m "Create a new branch."' Two steps, but like you said, it's probably not something you'd be doing very often anyway.
For example, 'git help checkout' clocks in at 236 lines. 'git checkout' can change the revision/branch you're at, create a new branch, or revert files without changing HEAD.
The help output for the equivalent Mercurial commands:
* hg help update: 38 lines * hg help revert: 41 lines * hg help branch: 24 lines
If I want to revert a file's contents in a git repo I need to wade through 236 lines to figure out the exact command I need. With Mercurial I need to wade through 41, because I know: "Oh, I'm reverting a file, I need an 'hg revert' command of some kind."
Mercurial commands each do one thing (rarely two, almost never more than that) and do it well. If you want to combine commands, write a script. This makes the documentation concise and easy to read as you're working.
Git commands each try to be flexible enough to do many different things. The price you pay is that any time you need to read through the documentation it's an exercise in trying to search for a word in a man page and hoping everything you need is somewhere nearby.
* Use hg branch <branchname> like git. The problem is this always requires me to do a push -f, which doesn't feel right...
* Use clone. Really? For a feature branch?
* Use the LocalBranches extension. Really, feature branches (the #1 productivity gain since switching to DVCS) isn't in the core code?
I have yet to find an equivalent to what I consider a core git workflow.
I'd probably use a named branch. Yes, you have to use push -f the first time you push that branch to a remote repo, but I think of that as a "hey, do you really want other people to see this work-in-progress branch?" safeguard.
While Git and Mercurial are nearly isomorphic in implementation, their UIs differ significantly because they're written with different models of DVCS in mind.
Basically, I would argue you haven't fully grokked Git. To the extent that I have understood Git's model, I have found it extremely insightful; if you want this insight, you should spend a little more time trying to understand it before giving up on it.
So basically, he's got the freshest possible eyes to make this judgement, and if your counterclaim is that he hasn't truly grokked it yet, then that suggests that it may be counterintuitive.
Additional fairness: the project in question is a 6-week round-the-clock code fest. Writing a kernel from scratch takes forever. (Is this project just a waste of time? Having moved on to poking at the Linux kernel and stuff, I'd say almost certainly, but that's a topic for another conversation.)
Most Sincerely, Alex "Found out the hard way that reset != revert" Gartrell
Or proper usage wasn't explained to him correctly.
That's an assumption.
You should say, "it may be counterintuitive to him". Intuition is based on past experiences and our internal metaphors. We have no reason to believe that his "intuition" is the same as most of the population that would use git.
The rest of the clown-car VCSes use "revert" to go back in time to that commit in the history.
Mercurial uses hg backout to start a new commit that backs out a previous commit, hg rollback to undo the previous transaction (without a separate commit), and hg revert does undoes the uncommitted changes in your working directory, very similar to MS Word's (now defunct) and Photoshop's (still active) File > Revert command.
To me, revert means "revert all my changes to the last saved version", which is exactly what Hg does.
To me, revert means "stage a new commit that reverts this commit in the history as if it never existed".
When I first used svn, I really expected 'revert' to mean "revert this commit". I also 'intuitively' expected it to have something like git's index, and ended up just working around that by just laboriously creating my own set of patches to feed it in another checkout. Not everyone's mental models line up — we are both free to consider one another as a moron (see also: politics, religion).
I think it's valuable to read the opinions of people who are just getting into this game. Those of us with lots of experience with the everyday tools of the trade might not see a lot of substance to this critique, but it's important when designing any product to make sure it's approachable for novices. There's often a tradeoff there for power or flexibility, which git has been unwilling to make (probably rightfully so), but it does seem that things could be done to make the tool easier to get into, without necessarily compromising its power.
Although I haven't used Mercurial, all of the issues he brings up I found really easy to solve when I started using Git (~2 years ago). The number and quality of online resources has only improved since then.
It was how I learned Git actually; it made the UI very similar to mercurial's UI. It was actually a surprisingly good learning curve, because it allowed me to experiment with git commands side-by-side with cg commands on the same repo, and I slowly transitioned out of cg into full-fledged git, almost without noticing. I'm a little sad it's not maintained.
Git is like a swiss army knife. git checkout can do just about everything and anything. Mercurial seems to be more split. hg update and hg revert do separate things.
Again a lot of preference comes down to personal feel. I prefer modularity. Others may prefer one tool solving it all.
git_remote_branch version 0.3.0
Usage:
grb create branch_name [origin_server]
grb publish branch_name [origin_server]
grb rename branch_name [origin_server]
grb delete branch_name [origin_server]
grb track branch_name [origin_server]
There are also plenty of aliases for the various actions. create: create, new
delete: delete, destroy, kill, remove, rm
publish: publish, remotize, share
rename: rename, rn, mv, move
track: track, follow, grab, fetchOkay, now no one has to comment anymore; I've taken care of all of it.