Aaron Griffin wrote:
I use git stash when switching back and forth between branches when I am of the mindset that "oh this isn't commit-able yet".
I keep noticing you mention "multiple branches in the same tree", but am at a loss as to why that's necessary. git offers the same functionality, mainly due to the fact that a "git checkout" is as quick as a "cd".
git co master ...change... commit git co branch-a ...change... commit ..change.. stash git co master git stash --apply commit
I guess I can't think of a good use-case when you would want to edit foo.c from BOTH master and branch-a at the exact same time... it seems like an attention killer to me. Like watching two TVs at once or something.
Could you explain why you would need the files side-by-side?
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep track of what I am doing by persistently retaining directory contents than by having a single working view and everything else being stashed away to be retrieved later. One example of where git stash is more cumbersome is if you've created new files but haven't added them to the index yet. You have to add them to the index before you can stash. Now this is not a huge deal, but it does require more work to prep your tree for a stash than simply cd'ing out to another branch directory would take. There may be other cases where more work is involved in stashing (above and beyond having to actually run the git stash commands and maintain the list of stashes) than is involved in using locally stored branches, but I haven't used git stash enough to discover them. It would not surprise me to learn that there are lots of subtle details to be aware of when using git stash. Parallel branch directories have an advantage over git's branch views whenever you need to compare the contents of branches. With parallel branch directories, all of the contents are there so you can compare them however you want. Additionally, you can compare things with parallel branch directories that you can't compare easily with git: for example, if I have a branch with a bug fix on it, and I want to compare the behavior of my program with the behavior of my program without that bug fix, or maybe with a different bug fix, I can build both in parallel and run them however I need to to make these comparisons. With git I guess I'd have to make my bug fix, build it, stash the code and copy the build directory somewhere else, then checkout the other branch, and build it, and then I could compare what I have just built with what I copied away somewhere else. But then if I want to make a quick change in the other branch and see how it affects the program output, I'd have to run a bunch more git commands and do lots more juggling to get back to the other brach, make the change, compile it, copy the results elsewhere, re-stash, un-stash, etc etc. Maybe it's because I'm an emacs user and not a vi user, but I don't like to keep track of any more stuff in my head than I need to. And keeping track of what changes I've stashed away from which branches and what sequence of git commands I need to run to return myself to a prior state when I was working on something else, is just more mental effort than I want to undertake. I find it so much easier to just leave a branch subdirectory and when I return to it later, it is guaranteed to be exactly as it was when I left, without any effort on my part. If I am working on 4 or 5 bugs in parallel (which I have certainly done at work, where working on just 1 or 2 bugs at once would be inefficient because of the downtime associated with building each tree) I can't even imagine using git stashes to sanely keep track of everything.
- A single branch-based 'view' that switches your files around in-place as you change which branch you are on, instead of keeping branches in separate subdirectories
See above - I don't get how this is a con, as branch switching in git is painfully quick
If quickness is all that matters, then I can guarantee that a simple 'cd' is even faster than git, no matter how fast git is. But quickness is not all that matters, and as I have described above, being able to view branches in parallel, and work on them in parallel, without any intervening git commands or mental effort in juggling stashes, and with the ability to keep parallel builds and use the build results in parallel, are much more important and for me, greatly favor parallel local branches.
- Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly
git is focused on file contents, and doesn't really care where those contents actually are. It seems odd to me too, but I have yet to discover a case when this is a big deal - I mean if I'm looking at some C code, I don't care if the file is named something.c or SOEMTHING.c or omgwtf.c - it's the code that matters.
The problem comes when someone, in a branch, renames a file, and then tries to merge their changes into another branch in which the file was not renamed. Unless file renames are tracked, the merge becomes very difficult. Refactoring a subsystem on a 'workbranch' is something that is done sometimes on large projects, and with git, I would expect that to be basically impossible to do sanely. Even if git's 'detect renames while examining history' technique did work, it still makes renames cumbersome, because you can't rename a file and change its contents at the same time or else git has almost no chance of detecting the rename via history. And if you can't change a file and rename it at the same time, then you can't, for example, properly rename a Java class, because the class name and file name have to be the same. So you'd have to rename the file (thus breaking the build, because the file would no longer compile), check that in, and live with having a broken build for a bit until you modified the file's contents to match its new name, tested it, and checked that in. It just shouldn't be that hard. File names are part of the metadata that is relevent to versioning. So the version control system should track file names properly, along with every other thing about a file (such as its contents and permissions). The fact that git doesn't do this is a serious oversight and I guarantee that eventually the git developers will have to face this and make some major changes to git. Either that, or they will just stubbornly refuse in the face of valid reasoning to the contrary. Bryan