Git 2.0 release notes
git.kernel.org
git.kernel.org
Perhaps git subtree just seems so good because submodules are so clunky. If only someone would invent a "best of both worlds".
Also, if you have a very large submodule repository, it won't inflate the size of the repository that contains it.
To respond to the comment about this being useful for private keys: if this is the case, does this also mean unauthorized users will not be able to checkout the submodule at all? Or will they just get a copy of the files (which would not make sense with private keys).
You seem to be very knowledgeable about subtree, so I'll ask a question you can hopefully answer:
I have multiple repositories each having 100,000-500,000 files, all relating to the same project. The reason I broke them up to multiple projects is that the git index doesn't handle millions of files all that well (e.g. index gets rewritten on every modification). Would subtree help me here in any way?
Of course, this is not a usual way to use git, and Facebook opted for switching to Mercurial when faced with a similar problem (though an order of magnitude or two larger, I'm sure).
submodules work for me now, but they are very clunky -- but the reason I didn't even try switching was the crypto signing of commits, which is apparently not a problem. Would subtrees help me with the scale as well in any way?
But I think for your use case you're probably stuck with submodules.
I've personally noticed that most devs don't have an opinion either way since they don't use subtrees nor submodules.
I don't know what subtrees offer but using submodules has been very pleasant once you know how they work. For example if you version control your .vim I think that adding submodules for extensions is way better than cloning them inside your .vim.
I look forward to having the opportunity to use subtrees.
[0]: http://blogs.atlassian.com/2013/05/alternatives-to-git-submo...
Once you have submodules in your repo, all that becomes heinous. PLUS everything you mentioned...
Sure, if you don't use those features, then submodules would probably work fine. But then why not just use Dropbox?
Subtrees are quite different from either. They make the imported repository literally a part of the commit graph of the parent tree through a subtree-merge-commit. It then does some extra work to help you bring in new changes or export new changes back.
I think it's a better approach than either, but it's also not exactly the same thing, basically.
Sure, arguably there are fundamental issues with submodules that you won't ever solve, and some people might prefer subtree to become the default. (I won't get into that argument here as there is another thread addressing that topic.)
But the fact still stands that a lot of the ugliness of submodules comes from the fact that the UI forces users to learn a whole extra set of commands, while the regular commands are largely oblivious to the existence of submodule. If I make a Git repo with submodules, I can't just pass a link to my Git-novice friends and have them clone it, because the UI for submodules is separate from the main Git UI. Arguably, for users who don't need to actually touch the submodule, the fact that the submodule is there should be invisible from the perspective of the UI. Although Git has been gradually getting closer to this being true, it is not currently the case (clone being an example of one command which is not aware of submodules by default).
hg push -- pushes everything to "default push location"
hg push -r . -- pushes currently checked out branch
hg push -r foo where -- pushes foo to where> If ping was designed by the git people: net-ping host --no=dns,bind --proto=TCP,rfc:492 eth0@ipv4::http://1.0.0.127.IN -ADDR.ARPA --stats -v
git checkout --ping
(Checkout already does too much; one more doesn't hurt).Edit: Ah, hmm, maybe the satire is more along the lines of "a single command does too much stuff", which does ring true for commands like `checkout` and `reset`.
hg push [dest] -- Push all local bookmarks that match a remote bookmark
hg push -B [dest] -- Push a specific local bookmark to a remote
To me those semantics don't seem particularly simple or flexible. In fact it seems quite like the semantics git is moving away from but with the restriction that local names and remote names always have to match, which means that you have to be very careful naming your local bookmarks to avoid clashes.Pushing only the current branch by default is a good thing, I think. If you are using a more centralized setup you can change the configuration of push.default to 'matching'.
It's just you.
It's about time we'd put "hg vs. git" to the category of flamebait topics (similar to "emacs vs. vi" etc) that should be avoided. Every time there's a git topic, someone comes and derails the whole discussion with a not-quite-apt comparison with hg.
AFAIK, there are decent two-way conversion tools so you can use hg with a git repo and vice versa. There should be no need to argue because you can pick the one you like and use it.
I think the OP makes a valid and argumented point.
E.g. "git push", similarly to "hg push" - without any extra arguments - do roughly the same thing, "push to the default location".
When was the last time you ever saw anything useful or insightful in comments about git vs. hg? There have been a few enlightening blog posts on the subject but discussion threads like this don't really provide anything of value.
What kind of comparison are you after?
To be more scientific, let's take "git push where" and "hg push where". Now count the number of ifs and buts that you have to keep in mind when using Git (am I pushing to the same remote? is the branch "set to integrate"? does the remote has this branch name?) versus plain "push everything to where you cloned from" in Mercurial.
My point is that Git has accumulated too much cruft and has introduced one too many concepts to be usable.
Git push by default pushes to where you cloned from. If you want to push to a different remote, you say so: "git push another-remote". If the remote doesn't have that branch, you create it, same as you would with bookmarks in mercurial.
git push == push all branches to origin hg push == push all changesets to origin
Your point is totally invalid, since git is self-evidently successful, and regarded by many people as usable.
The "cruft" you've pointed to consists of usable, useful features. So it would be useful to talk more about areas in which git could improve—even if that involves looking at features from Mercurial—rather than engaging in vague and abstract descriptions of "cruft".
With Git, it gained popularity not because it was terribly usable [1] or generally good (it was not even going to be an SCM [2]), but because it was imposed by Linus onto a pretty large number of developers - kernel hackers, not less - and then it spread from there.
[1]: http://marc.info/?l=git&m=111377572329534 [2]: http://marc.info/?l=linux-kernel&m=111288700902396
I'm also aware that nothing you said actually dealt with the fact that git is not unusable. In fact, it's objectively pretty good—if it weren't, we'd all still be using SVN.
What you seem to be saying is that you prefer the UX of Mercurial. Cool, that's fine - but I'd be keen for people to invest their time in improving the experience of using git, rather than bellyaching about perceived differences which aren't really all that big.
(As an aside, I don't really agree that there's a problem with git's usability. It's a complex tool, if you want it to be. But for day-to-day distributed SCM, you'll rarely have to care about most of that.)
Again, popularity has nothing to do with merit. It's a pure happenstance that Git was chosen over Mercurial for kernel development, and it all went from there.
The UX of Git cannot possibly be improved in the foreseeable future as it will be a _massive_ pile of breaking changes with people moaning all over the internet.
If you're looking to derail this post and do some trolling, then congratulations. You're off to a great start.
This (root) comment here is a good example: it isn't in any way related to the new developments in Git, repeats very basic comparison done many times already and fails to account for deeper differences and options (like the fact that you can easily configure git to make git push do exactly what you want).
It would be good for overall discussion quality if posts such as these were kept separate from the interesting stuff.
"Mercurial is so much simpler than git" is only true for one reason: You prefer mercurial and dislike git, and so you look for flaws in git while glossing over flaws in mercurial.
Mercurial tracks changesets. Git guys are inventing all kings of weird entities. Local branch? Mutable branch? Do these kind of things have separate sets of semantics in the git world?
In mercurial, branch is just a constant name for a group of changesets. Bookmark is just a temporary pointer to the changeset. Head is a changeset (that have no successors). Phase is information about whether it is safe to modify changeset. Mercurial is indeed a lot simpler.
Local branch == Bookmark with unpushed changesets
All branches and commits/changesets are treated equal.
Yeah. In mercurial you have Branches and Bookmarks. In git you just have branches. Head is the current checked out commit/changeset. Git doesn't allow you to alter commits, only branches, so every modification in Git is inherently safe.
Mercurial has some neat features, but this idea that it's always easy to use and git is always hard to use simply isn't true.
[1]: https://air.mozilla.org/changesets-evolution-with-mercurial/
And as anton_gogolev mentioned, ChangesetEvolution[1] will probably help augment HistEdit and Rebase for a number of operations. It will allow pushable history rewriting.
You answered that in your first paragraph: for many years, the first time people looked at Mercurial the answer for that class of problems was mq. The problem now is that it's still easy to find stale internal documentation, old blog posts, etc. which haven't been updated with the new recommendations. I thought that it might be worth having a small campaign to encourage people to update old wikis, contact blog authors, etc. when they find those recommendations and suggest a simple “this is no longer recommended – see …” update.
I think git branches correspond more to hg bookmarks, than to hg named branches.
To quote my other comment:
* Branches (named and unnamed) are part of core mercurial.
* Bookmarks are part of core mercurial.
* Multiple heads are part of core mercurial.
* Phases are part of core mercurial.
* Secret changesets is part of core mercurial.
* mq is distributed with Mercurial.
* Local branches is an extension that isn't part of core mercurial, I'll give you that. However, calling it a "third-party extension" is pedantic. It's listed on the official mercurial web site, and using extensions is much more a part of every day usage of mercurial than using extensions in git, for example.
Mercurial itself has just heads, which can be named or not. Bookmarks are orthogonal to the whole thing.
Anyway, you are plain wrong.
* Branches (named and unnamed) are part of core mercurial.
* Bookmarks are part of core mercurial.
* Multiple heads are part of core mercurial.
* Phases are part of core mercurial.
* Secret changesets is part of core mercurial.
* mq is distributed with Mercurial.
* Local branches is an extension that isn't part of core mercurial, I'll give you that. However, calling it a "third-party extension" is pedantic. It's listed on the official mercurial web site, and using extensions is much more a part of every day usage of mercurial than using extensions in git, for example.
edit: formatting.
Local branches in Hg is the same as bookmarks you havent pushed.
Remote tracking branches in Hg would be bookmarks you have pushed.
The problem with git is that new options aren't simply ignored by old git versions, meaning that if you synchronize your gitconfig as part of your dotfiles, then the machines that have old git versions will start spitting error messages at every command for options specific to new versions. I learned that painfully with push.default=simple.
For `pull.ff`, old versions will simply ignore the setting. I know because I wrote the patch ;-)
Edit did you mean to say (plus)feature or is something ruining the formatting? That seems to be how to specify only one branch. Yuck.
I'm lucky I haven't run into this, I guess, because I set my push default to simple a long time ago, so long ago I can't even remember why.
git push -f (enter) => Death to all branches. git push feature -f => Can only ever force push the feature branch
No matter when you press enter in the second line, intentionally or accidentally, you can't break all branches.
[push]
config = default
default = tracking
I once made a virtual machine and didn't pull in my usual .gitconfig. It ruined my day.on long running features, you 1. want to save your state off of your laptop and 2. keep it clean for your own review and for others' review. thus, force push is required, otherwise you'd have to keep making new revs of your branch (branch named joeblow/my_feature_rev_4).
The fact that git lets you shoot yourself in the foot doesn't mean you should, definitely not incorporate this into working procedures.
If it's a private feature branch, don't make it public (pushing would still back it up on the server, though you'd have to know the sha1 to fixed it). If it's public, don't rebase it.
And yet you don't know the reason. It's because others may have merged your work or be dependent on it. In my case, that doesn't happen, because it's a private branch. I'm the only developer, but other people can look at it for review.
"add -p --all some_untracked_file" does nothing, "--interactive" does something completely different; a menu system, not a "yes/no/etc." patch prompt.