4 ms·
me neither, but now I understand why some discourage the concept of creating many tiny branches in hg. [you can't delete them -- i still find this hard to belie
by angerman 14y ago
me neither, but now I understand why some discourage the concept of creating many tiny branches in hg. [you can't delete them -- i still find this hard to believe]
- anthonyb 14y agoI've never really understood the way that you can rewrite history in Git. It seems really odd to me - completely counter to the idea of having a repository in the first place. From the article: That is why git branches are so useful; you can do absolutely anything that you want with them. When you are done with the ‘quick-fix’ branch, you can just remove it, and nobody has to know it existed That actually sounds quite horrible. What if you make a mistake and remove a branch that you didn't want to remove? What if you remove the branch and nobody has any idea where change 'x' came from or why?
- vibrunazo 14y agoYou're removing the branch, not the whole commit. They can still see where the change came from by looking at the commit history and message. But they don't need to know how you locally organized your own self when you did it.
- tbatterii 14y agomercurial patch queues are for that kind of workflow.
- regularfry 14y agoCan you have more than one patch queue going at once?
- tbatterii 14y agoI could. And I have. And I do. But I know what I'm doing with them :) My point was that patch queues are more for the kind of workflow that might be experimental in nature, that you might not want to land on the mainline for a while (if ever).
- regularfry 14y agoHow? I thought you could only have one patch series going at a time.
- tbatterii 14y agomaybe I am misunderstanding your question. Can you give me an example?
- regularfry 14y agoWith git, you can have more than one experimental branch going at once, with more than one commit in each, and switch between them at will. I don't know how to do that with mercurial. It might be possible with a version controlled queue, but if it is I don't know the cli calls to make it happen. Here's a hypothetical git workflow: git checkout -b experiment_1 git commit -m "A" git commit -m "B" git checkout master git checkout -b experiment_2 git commit -m "C" git commit -m "D" At this point, I've got one experiment going with A and B, and another with C and D, both branching from the same master commit. My understanding of mq is that I could have either experiment_1 or experiment_2, but not both. Admittedly it's a situation which doesn't come up often, but it's just often enough that I'd be intrigued if hg could do the same.
- tbatterii 14y agoI do that by pushing, popping and reordering patches. For example right now in my queue I have a patch to disable http throttling on our main app which will never be checked in, a patch for a major refactoring of the data layer that might not fly, but the work is more significant than a couple days work, an upgrade to a new version of the sdk in another patch, a re-working of the docs patch etc.... I qpush whatever I want to work on between bug fixes which go directly to the development branch. so something like.... hg qpush --move nothrottle.patch hg qrfresh # repeat etc... hg qpop # unapply patch from working directory hg qpush --move membership_schema_refactor.patch hg qrefresh # repeat etc.... hg qpop #unapply I haz bug to fix hg commit -m "fix this bug" hg push && hg pull && hg update development # do the sync dance hg qpush --move membership_schema_refactor.patch hg qfinish -a # change applied patches to changeset Between the popping in pushing, I can switch to whichever branch revision I want assuming whichever patch applies cleanly. Not saying it's the same as the hypothetical workflow in git, but it is how I handle multiple seemingly unrelated lines of development for better or worse. Hell of a lot more flexible than what I would have to do in perforce before they added shelving etc.... :)
- anthonyb 14y agoBut if you delete the branch, how are they supposed to see the history? You'll just have a bunch of commits appear in master. The commit message will help - if they've left something decent.
- ktosiek 14y agoThe history for every change in existing branches is recorded - if you remove a branch you either want to discard whatever changes where there or you merged it into another one and don't need it tagged as separate branch. Commits in git are reference counted - the ones that have no references to them are removed, (and having a branch or other commit pointing to yours both count as references) and the ones that can be reached from tops of branches or tags are kept.
- alinajaf 14y ago> What if you remove the branch and nobody has any idea where change 'x' came from or why? If you want to make it clear that the change was from a branch, you can merge with --no-ff and you'll have a merge commit. What you call 'rewriting history' is just moving pointers around a tree. Git maintains a non-linear history of development, entirely orthogonal to the concept of branches. This means that for branches with significant amounts of work, you can get a good idea of why there it diverged from master just by inspecting the history. A pointer pointing to the last commit before merge is nice to have, but you don't lose much when you delete it.
- dmdeller 14y ago> What if you make a mistake and remove a branch that you didn't want to remove? In Git, a branch is just another name, like an alias, for a specific commit. Think of it like DNS, where the branch is the domain name and the commit is the IP address. 'quick-fix' => d34db33f When you commit to a branch, it just updates the name to point to the new commit. The new commit points to the old commit, that one points to its previous one, etc., until you reach the beginning. It's a linked list. When you 'delete' a branch, you're just deleting the alias named 'quick-fix'. You're not deleting the commit, d34db33f, or any of the other commits that it points to (assuming that d34db33f is still pointed to by other commits, i.e., you merged it into master or another long-lived branch). You can get it back again at any time: git branch quick-fix d34db33f This will create a new branch named 'quick-fix' that points to the commit d3adb33f - the same commit the previously deleted 'quick-fix' branch was pointing to - which effectively restores the branch exactly as it was before it was deleted. A merge is just like any other commit, except it points to two parent commits instead of one. I usually suggest to new git users that if they're really afraid of losing track of old branches, they can make them into tags after deleting. A tag is really just a read-only branch; it's an alias for a commit that you can't add new commits to. Once the user gets more comfortable with git, they usually don't feel the need to do this any more (since, as above, you can always just get the branch back by looking at the history - in practice, you almost never need to do this).
- dexen 14y ago> What if you make a mistake and remove a branch that you didn't want to remove? Threre are three cascading safeguards: * you cannot remove the current branch, you gotta check out some other branch. Thus you get to know what you leave behind and what you get into. * if you try to delete a branch not yet merged into another one (i.e., your changes would be lost), Git warns you and asks to use a different switch (-D rather than -d), * and the last line of defense: in normal configuration, Git stores history of all operations on HEAD (whatever is the current branch) in .git/logs/HEAD. If you remove or lose any branch or changeset you were working on by a mistake, you can easily find it in the log and git-checkout it (or git-cherry-pick or git-merge). At any rate, you can easily push your temporary branch to some other repo once in a while -- to have it thus backed up . You can easily remove it from the other repo once you are done. > What if you remove the branch and nobody has any idea where change 'x' came from or why? I describe that (the sense of changes) in the commit message. In my experience, branch names are somewhat ephemeral. I really don't want to carry baggage of 4 years of small featur branch into the future. Even the `big, official' branchech change ovre time; whatever is `devel' today, will be `stable' next week and `legacy' the next quarter. Keeping all that baggage in a long-running project would be distracting.
- CJefferson 14y agoWhile I agree with those safeguards, the big disadvantage (particularly when working with a large group of people) is that they are all defeatable by a stupid / uninformed team member, particularly if it isn't noticed for a couple of months. Of course you can argue that we shouldn't work with stupid / uninformed people, but often it is unavoidable.
- uxp 14y agoThat's the beauty of a distributed VCS. If my team member deletes every commit inside his master and tries to force push that to GitHub, either by accident or by malice, I have the true history for my master sitting on my local machine. I can then revoke his push access to our upstream, re-push the true master history I have a copy of, and then write him up for being stupid and/or uninformed. It doesn't matter if he was able to do that in HG or Git. If no one notices that such a thing happened for a couple of months, then we need to use better code review practices. Git won't prevent humans from making mistakes. Git will, however, complain if I try to push my master to the upstream's master and the histories don't match (if someone else deleted a previously merged commit), which can at least tip me off to something fishy. Then, I can either force push, and then tell all my other co-workers that the history has changed, or I can revert the destructive commit and carry on.
- kzrdude 14y ago> I've never really understood the way that you can rewrite history in Git. It seems really odd to me - completely counter to the idea of having a repository in the first place. Git is data-centric. It matters less how you used git to produce the final result (string of changesets), what matters is the changesets themselves. This comes out completely naturally since it's an evolution of Linux' patchstack development model.
- CJefferson 14y agoThat's an interesting viewpoint, which explains some of the problems I have been having with git. I can see that git is a very natural way of storing, modifying and passing around change sets, to a range of people. I previously used svn more for a way of 'recording all of history', and it annoys me that git really feels like it fights against this viewpoint. I can see why, as recording all of history makes passing around, changing and merging changesets more a pain. Don't really have a solution to this. Might try hg, as it might fit better with my mental model.
- rogerbinns 14y agoThe biggest difference is in defaults. Hg defaults are more applicable to smaller teams while Git's are towards larger ones. (You can always apply extra flags to get the desired behaviour in either case.) For example with tags a `git push` does not send them to the other end. If 1,000 people are cooperating then you don't want to see everyone's tags. (`git push --tags` will send them.)
- qznc 14y agoThere seems to be a philosophical difference between the communities. Hg is about replicating a single repository, while git is about a distributed system of repositories. Git embraces the fact, that every participant has full control about his data and assumes you want to publish cleaned up patch sets instead of all of your honest messy history.
- viraptor 14y agoHard to believe, because it's not correct. Actually they can hidden via `hg ci --close-branch` (still available, but doesn't appear in listings), or removed completely by running `hg strip "branch(branch_name)"` on it.