Great write up. I’d wish now for a Mercurial problem summary from him now just to lear what are the key problems in his opinion.
Huh, nameless workflows. I should try that.
The nameless workflows and workspaces reminds me a bit of using Gerrit: you push an unnamed thing (a ref) to another ref to open a change list (aka, a PR). No need to name a local branch.
Unfortunately, a little bit of metadata is still needed (namely the “Change-Id” line in the commit message), so Gerrit can track revisions of a change across refs. But in theory that could be stored in a way that it’s invisible to end users, and be tracked across rebases and amends.
Me, too! My previous team used hg named branches as feature branches (they had, a few years before I joined, migrated from CVS to hg so this was a huge step up) and their workflow bloated the shared repo to such an extent that occasionally clients would fail to push/pull because there were too many tips to compare.
Personally, I really like having a staging area by default. I like my commits to have higher granularity (i.e. do one thing in a commit). When editing code, I will often make several commits worth of modifications before finalizing on what I want to change. I also usually have some modifications (i.e. debug printfs or minor build file modifications) which I don’t want to commit, but I may need to commit other parts of those files. Having a staging area makes it easier to pick-and-choose what parts of what files go into each commit. It could be argued that what I really want is just git add -p, and that the staging area is irrelevant to that. However, I like the interactivity that a two-phase commit process affords (and the ability to easily undo changes). In the article, Szorc argues that this shouldn’t be a default feature, but this seems to be a very common use-case (especially once multiple people start working on a project and you want a clean commit-history).
git add -p
Initially, I too thought that this was the argument that he was making, but if you think it through, and understand the nature of the what happens when you git add -p, it’s exactly the same as what happens when you commit, without the commit message. Git creates a copy of the file in the objects folder, takes the hash and names it appropriately based on the hash. The commit is just putting a label to the stuff that you put into the index (/staging area). Conceptually, there’s no difference between writing a label on an envelope and then one or more things in it vs putting one or more things in it and then writing a label on it. I’m a decently experienced git user and can see how the simplification of removing the staging area would make understanding git easier.
One of the places that it might make things harder is in resets - i.e. I’ve committed and I want to reset --soft HEAD~1 to redo the commit. It would be difficult to keep the existing changes in my workdir and the reset files separate. Perhaps there’s an obvious way around this though?
reset --soft HEAD~1
The workspaces idea is really interesting… it would be cool to see some sort of experimental interface built around it - use a single object store and somehow ensure that proper access controls are in place. I’ve played around with implementing a custom git-receive-pack and git-upload-pack using libgit2, but it’s a pretty large pain (or at least it was a year ago).
One thing worth noting: at least for the storage portion, GitHub almost definitely does something similar to this. If you ever push a commit to a fork, you can access that commit through a URL in the main repo. My guess is that they specifically push the forking model so they can save on storage.
As an example, you can take a look at these commits:
I really like his workspace idea. I’ve sent one patch to three or four projects; there’s no need for me to have a whole clone of them up on github gathering dust.
Would a PR from diff patch would be an interesting concept here ?
Can you elaborate? I’m not sure what you mean.
To this day, I’m surprised this isn’t a feature. I often only make one or two changes to a project, and would be happy to just push the refs (or create a patch) rather than forking and remember to garbage collect later.