I'm not sure what you mean by "we maintain extra repositories on a staging server for deployment". What exactly are you doing, why is that necessary, and what extra steps does it involve?
The "extra steps" (the index, remote branches, etc.) are there for a reason, and that reason is to give you the tools to be careful with your codebase.
I always use `git fetch`, for example, because unless I've been doing something reeeeally weird, `git fetch` will never touch my local work. At all.
The index allows me to make sure I know exactly what I'm committing, and the extra step gives me the chance to look over it once again before I commit. (`git add -p` and `git commit -v` help a ton here, even though it feels like they "slow things down"). I never have "Oops, I didn't mean to commit that" moments anymore.
And the merging model (yes, with those opaque commit-hashes and mutable history and 3 kinds of branches) allows me to fix things when I screw up (or one of my coworkers does). Which still happens all the time, because we're human.
I think you could get a lot more out of git if you were willing to invest the time to learn more about its branching model (which really is elegant once you understand it), and to configure it properly. Otherwise, you may have a look at Mercurial, which has a more svn-like experience.
I find the speed alone is worth it. Git lets me commit and branch without having to think about it, without having to enter the command and then pause for a while (even a couple of seconds is enough to break my flow) while it does its stuff.
Definitely; I used bzr for years before using git and always thought, "how much faster can git really be?" Startlingly faster.
preemptive disclaimer: I haven't used bzr for years and understand that it's faster now than it was. I liked bzr. blah blah I really don't want to start a flame war/pissing contest. But people should try git out before dismissing its speed as a worthwhile advantage.
This. Though mercurial has it's own set of issues, and it doesn't mitigate the DVCS problems with maintaining extra repos (e.g. you still have many more steps in your workflow than in SVN, and you still don't have nice short, ordered, global revision numbers).
The benefits of DCVS, and Git in particular, are pretty clear, specially as you scale the team size.
Git's command line is a UX train-wreck though. Poor consistency, learnability and leakage about how the internals work. I think Git gets a lot of unnecessary flak because even though people realize it's superior, they are always fighting it into doing what they want.
Hg is fine, and it saddens me to know it doesn't see more adoption because there isn't a big nerd behind it. Git has some important factors in its favor, though:
1. In my experience, it's more robust. I had Hg throw Exceptions doing menial tasks.
2. It's more popular, there's more infra-structure available. GitHub is a big factor until we get more competition on this area.
3. Since most commands are just scripts that call lower-level tools, it's potentially more flexible. It's possible to derive new functionality without hacking too much the VCS source. That could include a saner command line.
DCVS is a fantastic advance. Git isn't the best example of that, though. IMO, the UX problems of Git have everything to do with its internal model of revision history, not the structure of the internals. But I still pine for http://monotone.ca
I don't even get to code that much and I've found very compelling reasons to do all of:
- git rebase -i (the "cleaning" of history)
- git add -p (which requires a separate staging area)
- Using a bare repository (which, just for the record, I've also had to do with SVN, but we didn't have a special Googlable term for it)
- Track the difference between a local and remote branch (this is actually inherent to DVCS workflow, it's like going from DOS to UNIX and complaining that they make you track file permissions... you didn't even have the option on DOS!)
It's actually kind of embarrassing to see an SVN user claim that they don't understand the difference between a downstream concept of a central repository and the remote concept of the same repository, because I can sure as hell remember having to run "svn up" before "svn ci" just in case someone had made a commit to the remote repo in between the time of my last update and my upcoming commit.
master, "origin/master", and origin's own master all have corresponding concepts in SVN, even if master and origin/master had to be the same by definition.
One more thing: I'm pretty sure SVN now has only one .svn directory, just like git.
I feel your pain. It's not uncommon. I've managed teams using Git and consider myself mid-level using it, but give me a month without using it and I forget the sequence of commands (each with flags) I have to type... something that never happened with SVN.
I appreciate Git and hate going back to SVN when clients demand, but I'm convinced it takes a certain kind of brain to feel comfortable with it.
The thing I miss most about Subversion was the involvement of the whole team. git is only for programmers. Subversion was for everyone: our graphic designers had no problem with it, our project managers had no problem with it, our dumbest QA people had no problem with it. Subversion is easily used by non-technical people. There are many GUIs for Subversion that make it drop-dead easy to use. And there were big productivity gains to be had by having the whole team using the version control system.
git has cut the team in 2. The graphic designers no longer know how to commit their work, nor do the frontenders, nor do most of the project managers. In particular, when a conflict comes up, nobody knows how to resolve the conflict (with Subversion we had a simple rule: "If you get a conflict, save your work outside of the project, then "accept theirs full", then re-integrate your work. A pain, but non-technical people could manage it). Instead, all of those people now send their work to the programmers, via email or Dropbox, and they say "Please integrate this into the project". This increases the amount of work that the programmers have to do.
We now use git for everything, because it seems like it is the thing to do, and it helps the programmers merge their work together. But the price is high: the loss of half the team, who can no longer use the version control system.
Sequential commit numbers? How does that work with branching? Or other people's commits? eg. I commit #100, you commit #100, you pull my commit, now we have duplicate identifiers.
Git commit ids are a hash of the commit content. This has very nice properties in that:
- Ids are duplicate if and only if the commit is identical (the collision chance is so low it's not worth considering)
- It's content-addressable
And you can refer to it by any unique prefix, so it's not a pain to type out (and you should only rarely be typing out particular commits instead of branches or tags).
That right there illustrates the disconnect that causes some people to dislike git while others love it. Git is truly distributed.
In a distributed system, commits are not totally ordered. It is fundamentally impossible to give them all meaningful sequential numbers, because some are really neither newer nor older than others. They are "in parallel".
Git excels at truly distributed workflows, and distributed workflows dominate in open source. That's why git dominates the open source world. The basic issue in open source is this: code is shared across organizational boundaries. You need to make and deploy a change today, without knowing or necessarily even caring whether the upstream project is going to take the patch. But your code needs to stay consistent and cleanly mergeable at every point through this process, even as multiple patches are flying in multiple directions.
Mercurial is really nice, IMO. I always preferred it over Git due to the well thought out CLI. Unfortunately, it's usage hasn't seemed to catch on outside of a few (Sun/Java).
Git keeps getting better, and I'd be hesitant to put anything new on Mercurial at this point. The tooling just doesn't seem to be keeping up any more.
If people are using SCM for too many things instead of too few, then that's a major improvement. Git could be better, yes. I personally prefer Hg even though I almost never use it due to Git's ubiquity. But as far as switching to distributed SCM, we spent 2 or 3 years fighting to kill the crappy centralized SCM systems we were using and we'll go back to centralized over my dead body.. I'd rather deal with a less friendly distributed system than ever have to use SVN ever again and deal with all the merge nightmares.
While I'm not wild about all the eggs being in one basket, I find myself getting frustrated when code isn't on github, because I can't star/watch/track it from one central place. I use the star feature on github all the time to mark potentially useful/interesting libraries, and every now and then will browse through them to see which ones took off and which fizzled.
You seem not to be aware that there are also several GUIs for git?
The pain here is not because git is inherently harder, but because you'd gotten used to svn (including your conflict workaround) and I guess nobody wants to do the same learning for git.
SVN is waaay simpler. SVN is basically commit -a/pull/push. And even these differ in behaviour and semantics.
Recently I tried Tourtoise git and I came to the conclusion that a beginner will probably rather learn the cmd line version because he will otherwise loose code.
In SVN you still have to update (and in fact, if you try to commit without updating, it'll complain at you). That's the same as git pull. So all that leaves is one extra step, the push.
I have the (fairly unique, I suspect) perspective of someone who never had to extensively use SVN until recently (before git came around there was lots of Perforce and manually managing patches/tarballs).
SVN is unbelievably more difficult. The entire conceptual process of merging/rebasing/reintegrating is so much more difficult in SVN than git that I really cannot understand how people cope. Branches in SVN are such a pain in the ass that feature branching becomes a nightmare barely even worth doing. I get migraines trying to keep straight what things in SVN make changes on the server and what things make changes locally only that I can sit on for a while. Being centralized seems to raise the stakes of just about every operation, whereas with git I can take it slow, get everything right, and not involve other people until I decide it is the right time to do so.
A month-long stint of working with another team that uses SVN for some incomprehensible reason left me seriously considering seeing a doctor about some blood pressure medicine. I swear to the gods I would rather use quilt.
I've had far more pain with subversion than with git. Those .svn directories sprinkled everywhere are a pain, get deleted and cause problems when clients move folders around, and things like users renaming files to lowercase from uppercase caused a client's repository to get into an unusable state and was difficult to recover from - insanity! Having used SVN, I'd never willingly go back to it, particularly with clients involved.
For git on the command line, I use day to day 4 commands aliased:
alias status="git status"
alias commit="git add --all .;git commit -a -m"
alias pull="git pull --rebase"
alias push="git push"
So, typically
status - find out what's going on
pull - grab any changes from others and replay mine on top
commit - add my files and changes
push - at the end of the day send changes up to the server
Occasionally I'll use stash or tag, which are also pretty simple and straightforward. Yes the command line UI could be improved, but it's not much harder than svn or cvs.
This in particular I find curious:
We keep things under control by maintaining detailed sample scripts for everyone to refer to.
Why not set up a file with aliases in it if you are asking people to refer to cheat sheets? The basic commands as above are painfully simple, most people don't even need to branch and can get by just by pulling, committing and pushing, but branches aren't particularly complex in git either...
For non-programmer clients, for any version control system I'd get them to use a GUI like GitX, and they'll never touch the command line - that's very similar to svn GUIs, and frankly I doubt they'd know the difference.
It's high time this sort of version control was integrated into operating systems though - life would be a lot simpler if the Mac OS Finder for example had built in support for a common system like git with a user friendly front-end. I can't count the number of clients and colleagues who have made their own crude version control system by renaming files with version nos or initials to track changes - there has to be a better way.
> Subversion we had a simple rule: "If you get a conflict, save your work outside of the project, then "accept theirs full", then re-integrate your work. A pain, but non-technical people could manage it
The eureka comes when you stop using git by retrofitting Subversion workflow on it. The "Git forces me to learn obscure things" part precisely shows that.
The hardest part is not learning "obscure" git things, it's unlearning the habits and preconceived ideas about how SCMs work.
This is the key issue. I spent a year or two as a Git skeptic, but then I realised that git is the wrong answer only if the question is "What SCMs are out there that will magically improve version control while presenting me with an interface and workflow identical to SVN?"
Yeah, I think this is the killer, and it's been my experience teaching Git to others. SVN does have a mental model that makes more sense: there's my copy, and there's the server copy. When I finish, I make the server copy look like mine. Done.
The terminology used by Git makes things hard for people to understand, remote and local, branches here there and everywhere. The OP is right that the deletion syntax for branches is awful.
BUT
It's not magic. It's explained all very easily.
"The staging area lets you batch up your changes so you can issue multiple commands to add files, or get rid of them if you change your mind."
"Just use `git pull`. If you don't know why you need to `fetch`, don't do it. Git pull is just like an SVN checkout."
"When you commit, you don't have to send it to other people, so your work can be in a broken state, and you won't break it for everyone else. When you're super happy with it, use `push` and it'll be visible to everyone."
These explanations get people who understand SVN to get Git, and they understand exactly what Git is providing over SVN. Once I use these explanations, people never seem to have problems.
What seems to keep happening is they look on the Internet for solutions to issues, which tangles them up even further, with rebasing and such. Even the simpler tutorials like learn.github.com are obsessed with showing pictures of trees and different branching states that beginners simply shouldn't be exposed to. Their mental model is completely screwed up, and they start to blame Git (not unreasonably) rather than themselves. When SVN screw ups happen, they blame themselves because SVN is conceptually simple, so they know the mistake must have happened with them. Then I hear things like "This never happened with SVN" or "SVN was always so much easier". When I prod them about this, they do end up remembering that SVN had it's own issues, but they forget them when their current problem is Git.
EDIT: Oh, and the other problem is that some of the GUIs out there are criminally poor. Particularly eGit for Eclipse. It exposes a metric crapton of functionality that I have absolutely no idea about, and I've been using Git happily for two or three years now. I don't know about refs or anything, and eGit makes it all exposed and seriously painful to do anything. Having tried to help someone with it, I gave up. "I use the command-line. You think I use it because I am clever, but I use it because I am stupid. The command-line is much simpler than this car crash, and I have no idea how you have got as far as you have with it."
> The hardest part is not learning "obscure" git things, it's unlearning the habits and preconceived ideas about how SCMs work.
I've begun to think of engineer's ability to "get Git" as a sort of abstract-thinking FizzBuzz. DVCS breaks up some composite actions (svn commit/checkout) into their component parts (git fetch/merge/commit/push). If you can't make that mental leap and see the value in it (and accompanying tradeoffs) despite all the learning materials out there, how can you be expected to derive comparable evolutions of design and engineer on your own?
> Git allows the topic-branch development style, where you maintain one short-lived branch for every task you work on. Like many people, I learned about this style from distributed version control. I love it. It’s an excellent way to switch between tasks, and maps well to the way I actually think about the state of the project.
But you don’t need Git to do this! Subversion has “svn switch”. It does have an annoying problem that if you specify the wrong URL to switch to, it will trash your local copy rather badly. However, Subversion seems to have fixed that problem in version 1.7.
Quite an annoying problem. I'm not really sure why the author is a git skeptic if it enables and introduced him or her to a wonderful workflow.
The ability to easily work on multiple branches and make offline commits is a huge selling point for any DVCS. I really like git rebase and git add -p now as direct arguments for git, but wouldn't have used them right away.
You could do topic branches in SVN, it would just be painful. It's sort of like saying "Why use C++? You can do object oriented programming in C with structs and function pointers."
Actually, I like to avoid the bloat of C++ and just use "object-oriented" C with structs and function pointers wherever possible.
This is largely due to the fact that I have a strong aesthetic preference for languages where you can hold most of the language [1] in your head. Such languages are called compact [2].
[1] Compactness of language and standard library are different. Having a non-compact standard library isn't necessarily a bad thing, especially if it means I don't have to complicate my life with third-party libraries.
svn switch is much inferior compared to git checkout... it is slow and requires a server roundtrip unless you just use svn switch --relocate (which doesn't do the same thing, it happens to be a separate feature with the same interface).
All I remember from our SVN days was the constant disasters. It seemed like everything you tried to do more complicated than changing a couple lines would put the whole system in some horrible state that required gross things exactly like what this article was talking about (coping directories back an forth). And then, all that directory copying would just as likely make everything worse because the 400 little .svn directories were no longer consistent. Good riddance.
Coming from svn, the skepticism here is really about distributed version control, and being heavily involved with the vcs at all. (Being heavily involved with svn, like setting it up and administering it well, is really not that easy compared to just using git, what's easy is just jamming stuff into svn, as long as there are no conflicts).
Having a local repo and push/pull to any other repo is not a complication but a huge advantage. It lets you do things like commit while you are on an airplane, or share committed work in an internal team before pushing to trunk, or keep repo history even if the server dies in a fire. It lets you not have to worry about who can be trusted with commit permissions or not. Being able to commit all the time without pushing lets you keep revision history without checking in, so you don't end up with many copies of your working directories, or saving up changes before you are 'allowed' to commit.
Since you can commit all the time, you can destroy the working tree trying things out and then bring it back if they didn't work.
So let's not complain about having a working tree, local repo, or remote repo. The staging area makes it so that you don't have to complete all staging of many different files in one huge command. You can add/rm something, preview what's staged, and only commit when you are satisfied.
In addition, CVS type merge is a pain while it is actually much simpler with git or hg. And being able to keep rebasing your private feature branch on a changing remote branch is a huge improvement.
The OP says he is waiting for the git epiphany. The epiphany is that there is no _the_ remote repository. You can use git like it's subversion, and designate one repo as _the_ repo, but because git isn't designed this way it isn't going to help you much in this endeavour.
Git does have a high learning curve. And the command line tools are opaque, even to developers. Also, it forces you to have a mental model of the underlying implementation to know how to use its tools.
But underneath, the concepts are pretty simple, and because it's the right simple concepts, the things you can do with it are pretty flexible, and thus powerful.
Git's interface can defn be way better for the default case. But everyone and every team's workflow is different, so the inherent flexibility will always involve a little bit more complexity.
And oh, it seems that he hasn't yet discovered selective commits or stashing, so staging seems like an extraneous extra step.
And rewriting history seems frivolous if you work by yourself. But it makes pull-requests on open source projects way easier to manage if your commits are clean. And if you need to rollback to a working version of your production code, it helps to have clear commits too.
"it forces you to have a mental model of the underlying implementation to know how to use its tools."
This is a BIG reason why I recommend even to advanced Gitsters to use a GUI tool like Tower or SourceTree so they don't get confused or inconsistent about how their repo is structured. I've used Git for years and I can't keep it all in my head. Surely some can but not me and probably not most.
"I hate those .svn directories: they give me false positives when I’m searching my files, and it’s pretty easy to mix two incompatible working copies accidentally."
"You can use “pull” to mean “fetch and merge”, but some authorities will advise you not to. You can also use “commit -a” to avoid the “add”, but you still have to be aware of it."
Whatever tutorial I originally used to learn Git made use of `git pull` and `git commit -a` exclusively, without any elaboration. It wasn't until long into my Git career that I was even aware of `git fetch` or `git add`. To this day I use `git add` only occasionally (but it's so useful when I do need to use it), and I honestly can't think of a case where I've needed `git fetch`.
I'm about to teach my co-workers to use Git for a project I'm spearheading, and I intend to expose them to this simplified view and let them fill in the blanks when needed.
You'll probably like Mercurial better. However, the race has basically already been won by Git. I wish Git would be less confusing while still keeping its power. None of its terminology is intuitive, so you must spend a lot of unnecessary time learning git specific jargon to use it effectively.
Once speaking to a freebsd developer, he explained the problems with git in freebsd workflow.
His explanation was on the lines that if there are 100 developers working on different trees of freebsd and they want to commit their work, it causes a race, as if some one commits before you, you need to do a git pull, incorporate changes and then push, even when they are working on unrelated components.
My response to this was yes, and that is why git allows you to create branches so cheaply, but he still was not convinced.
I like rebase for this rather than merging the changes. But it's kind of strange to think of it as a problem that you'd need to acknowledge the other developers' work before committing...
Well, if 2 people are working on different files, they can commit their changes to svn without updating their local copy first. But in git you have to bring your copy to the same revision as the remote one, in order to push your changes, irrespective whether the changes you made our conflicting
I've developed a couple of Open Source stuff and I wanted to push them online. In my old company, they used SVN for almost everything (even Graphic designs, sometimes!) and hence I kind of knew SVN pretty well. I wanted to give GIT a fair trial, just to make sure I don't miss out something good, out of the personal bias in favor of SVN. And hence, I read some books, documentation and several other resources just to learn this GIT, simply because I saw it was a popular choice amongst many communities, including HN.
My thoughts in this entire learning process was along the lines of - "Why the hell are they doing it like this, instead of that? Why are they calling this, like that, instead of just calling it what it already is?"
In my experience trying to learn GIT, I was able to conclude that GIT introduces a LOT of terminologies, and concepts, making the path for beginners like me more and more difficult. Whether spending hours learning these concepts just to get your stuff synced properly depends on your scenario. But for me, SVN rules.
Also, there is another REALLY brilliant way by which SVN helps me. I use Tortoise SVN. I have a couple of external 1tb hard-drives to back-up my code. I like to take regular backups (obviously) because some of the code is in production and I just want to play it safe. Using SVN, on windows, I run an SVN server on my machine, and create respective repo's on my hard-drives and just update them and voila - I have all the code properly backed-up and versioned. You can also automate this (there are scripts to do them), but for me, I like to keep it synced manually. And also, you can keep your stuff backed-up to your Google drive by making a repository inside your drive folder. I can't imagine typing all these as commands in GIT.
I guess the significant difference is that with git, all copies of a repository are full working repositories in and of themselves. So there is no difference between the repository on your git server and the copy you cloned onto your workstation (that's why it's 'clone' and not 'checkout').
This makes some things easier. If the 'server' dies, you can substitute any other copy of the repository for the original. So if github disappears I can still continue to hack away on my code like usual (commit, branch, merge, etc), and if I decide to publish on gitorious or something later, then I just push my local repository up and everything is there (full history, etc). This sort of obviates the need for 'backups', since your copy is already a backup, but making extra backups of any repository is as trivial as copying it (rsync) or cloning it to somewhere else (cd /backup; git clone /myrepo) - so I don't need to run a server or anything to make backups.
As a thought experiment to illustrate the practical difference, consider why pull requests are so trivial to implement on github, and how would they work on the hypothetical svnhub?
> In my experience trying to learn GIT, I was able to conclude that GIT introduces a LOT of terminologies, and concepts, making the path for beginners like me more and more difficult.
So does Subversion, but you have already learned its terminology and concepts and are no longer a beginner.
"Git adds extra steps to the flow of content between your local files and the remote repository. "
This is the biggest issue I've always had with Git. I've struggled to understand why so many developers swear by a system that takes several steps backwards from other systems.
All those extra steps have a purpose, all those extra steps can be glossed over if you don't care.
git add is never needed if you always git commit -a
if you don't care what git fetch && git merge does, just use git pull
The biggest problem with learning git is that all git experts love to talk about the advanced workflows, but all the beginners just want to be able to push and pull.
I love Git, but a workmate of mine pointed out an interesting deficiency. During a merge from a branch some time in the distant past he said, "Hang on, who created this branch and when? I can't even tell." It would be nice to have a feature (even if optional) so that branch creation was recorded somewhere (similar to notes, perhaps).
I like optional, it seems like there's no reason there couldn't be an additional flag set at the time of branch. You do kind of know who branched though because aren't they going to have the first commit on that branch? But perhaps what you'd be looking for is something like the tag system where one could bring up all the branching at once in a big list...
the only thing i hear about members of our team missing from svn are using externals. one of our members would create an external in his current client project to our open source repo. now while working on his client project, if he encountered a bug in our open source project, he could fix and test in the client project, but the change would get committed to our open source project.
while git has submodules, they no way near have the flexibility of externals. if git would incorporate the idea of externals, I think it would cure quite a few people's complaints.
Having separate add and commit steps has improved my workflow.
If you do an add, followed by a "git diff --cached", you can view what's going to be committed before you do the actual commit.
I've found this workflow to be useful, since it helps see things like debugging print statements that crept in, or unnecessary files accidentally added ("git diff --cached --stat" is useful for the latter).
80 comments
[ 4.7 ms ] story [ 160 ms ] threadThe "extra steps" (the index, remote branches, etc.) are there for a reason, and that reason is to give you the tools to be careful with your codebase.
I always use `git fetch`, for example, because unless I've been doing something reeeeally weird, `git fetch` will never touch my local work. At all.
The index allows me to make sure I know exactly what I'm committing, and the extra step gives me the chance to look over it once again before I commit. (`git add -p` and `git commit -v` help a ton here, even though it feels like they "slow things down"). I never have "Oops, I didn't mean to commit that" moments anymore.
And the merging model (yes, with those opaque commit-hashes and mutable history and 3 kinds of branches) allows me to fix things when I screw up (or one of my coworkers does). Which still happens all the time, because we're human.
I think you could get a lot more out of git if you were willing to invest the time to learn more about its branching model (which really is elegant once you understand it), and to configure it properly. Otherwise, you may have a look at Mercurial, which has a more svn-like experience.
preemptive disclaimer: I haven't used bzr for years and understand that it's faster now than it was. I liked bzr. blah blah I really don't want to start a flame war/pissing contest. But people should try git out before dismissing its speed as a worthwhile advantage.
Git's command line is a UX train-wreck though. Poor consistency, learnability and leakage about how the internals work. I think Git gets a lot of unnecessary flak because even though people realize it's superior, they are always fighting it into doing what they want.
My pet project is giving it a saner command line.
1. In my experience, it's more robust. I had Hg throw Exceptions doing menial tasks.
2. It's more popular, there's more infra-structure available. GitHub is a big factor until we get more competition on this area.
3. Since most commands are just scripts that call lower-level tools, it's potentially more flexible. It's possible to derive new functionality without hacking too much the VCS source. That could include a saner command line.
Is this "pet project" still in the planning stages, or is it published on Github? If the latter, can we have a link to it?
- git rebase -i (the "cleaning" of history)
- git add -p (which requires a separate staging area)
- Using a bare repository (which, just for the record, I've also had to do with SVN, but we didn't have a special Googlable term for it)
- Track the difference between a local and remote branch (this is actually inherent to DVCS workflow, it's like going from DOS to UNIX and complaining that they make you track file permissions... you didn't even have the option on DOS!)
It's actually kind of embarrassing to see an SVN user claim that they don't understand the difference between a downstream concept of a central repository and the remote concept of the same repository, because I can sure as hell remember having to run "svn up" before "svn ci" just in case someone had made a commit to the remote repo in between the time of my last update and my upcoming commit.
master, "origin/master", and origin's own master all have corresponding concepts in SVN, even if master and origin/master had to be the same by definition.
One more thing: I'm pretty sure SVN now has only one .svn directory, just like git.
That was a more recent change in 1.7.x ( around late 2011?) and I know people who are still, in 2013, in 1.6.x
I appreciate Git and hate going back to SVN when clients demand, but I'm convinced it takes a certain kind of brain to feel comfortable with it.
git has cut the team in 2. The graphic designers no longer know how to commit their work, nor do the frontenders, nor do most of the project managers. In particular, when a conflict comes up, nobody knows how to resolve the conflict (with Subversion we had a simple rule: "If you get a conflict, save your work outside of the project, then "accept theirs full", then re-integrate your work. A pain, but non-technical people could manage it). Instead, all of those people now send their work to the programmers, via email or Dropbox, and they say "Please integrate this into the project". This increases the amount of work that the programmers have to do.
We now use git for everything, because it seems like it is the thing to do, and it helps the programmers merge their work together. But the price is high: the loss of half the team, who can no longer use the version control system.
> We now use git for everything, because it seems like it is the thing to do,
You nailed it. And IMO this current obsession with Git/Github is bordering on unhealthy. I really wish/hope this fad dies out fast!
Also anecdotal, but the graphic designers at our company have no problem using Git.
So much easier conceptually, the cmd line utility was written for actual humans, and it has sequential commit numbers.
If you see references to commits 143, 732, and 2021, you have some instant grasp on the ordering of those. acbe2f, 7624ab, bccc07 not so much.
Git commit ids are a hash of the commit content. This has very nice properties in that:
- Ids are duplicate if and only if the commit is identical (the collision chance is so low it's not worth considering)
- It's content-addressable
And you can refer to it by any unique prefix, so it's not a pain to type out (and you should only rarely be typing out particular commits instead of branches or tags).
That right there illustrates the disconnect that causes some people to dislike git while others love it. Git is truly distributed.
In a distributed system, commits are not totally ordered. It is fundamentally impossible to give them all meaningful sequential numbers, because some are really neither newer nor older than others. They are "in parallel".
Git excels at truly distributed workflows, and distributed workflows dominate in open source. That's why git dominates the open source world. The basic issue in open source is this: code is shared across organizational boundaries. You need to make and deploy a change today, without knowing or necessarily even caring whether the upstream project is going to take the patch. But your code needs to stay consistent and cleanly mergeable at every point through this process, even as multiple patches are flying in multiple directions.
Git keeps getting better, and I'd be hesitant to put anything new on Mercurial at this point. The tooling just doesn't seem to be keeping up any more.
The pain here is not because git is inherently harder, but because you'd gotten used to svn (including your conflict workaround) and I guess nobody wants to do the same learning for git.
Recently I tried Tourtoise git and I came to the conclusion that a beginner will probably rather learn the cmd line version because he will otherwise loose code.
SVN is unbelievably more difficult. The entire conceptual process of merging/rebasing/reintegrating is so much more difficult in SVN than git that I really cannot understand how people cope. Branches in SVN are such a pain in the ass that feature branching becomes a nightmare barely even worth doing. I get migraines trying to keep straight what things in SVN make changes on the server and what things make changes locally only that I can sit on for a while. Being centralized seems to raise the stakes of just about every operation, whereas with git I can take it slow, get everything right, and not involve other people until I decide it is the right time to do so.
A month-long stint of working with another team that uses SVN for some incomprehensible reason left me seriously considering seeing a doctor about some blood pressure medicine. I swear to the gods I would rather use quilt.
For git on the command line, I use day to day 4 commands aliased:
So, typically Occasionally I'll use stash or tag, which are also pretty simple and straightforward. Yes the command line UI could be improved, but it's not much harder than svn or cvs.This in particular I find curious:
We keep things under control by maintaining detailed sample scripts for everyone to refer to.
Why not set up a file with aliases in it if you are asking people to refer to cheat sheets? The basic commands as above are painfully simple, most people don't even need to branch and can get by just by pulling, committing and pushing, but branches aren't particularly complex in git either...
For non-programmer clients, for any version control system I'd get them to use a GUI like GitX, and they'll never touch the command line - that's very similar to svn GUIs, and frankly I doubt they'd know the difference.
It's high time this sort of version control was integrated into operating systems though - life would be a lot simpler if the Mac OS Finder for example had built in support for a common system like git with a user friendly front-end. I can't count the number of clients and colleagues who have made their own crude version control system by renaming files with version nos or initials to track changes - there has to be a better way.
You can do this in git as well.
The eureka comes when you stop using git by retrofitting Subversion workflow on it. The "Git forces me to learn obscure things" part precisely shows that.
The hardest part is not learning "obscure" git things, it's unlearning the habits and preconceived ideas about how SCMs work.
The terminology used by Git makes things hard for people to understand, remote and local, branches here there and everywhere. The OP is right that the deletion syntax for branches is awful.
BUT
It's not magic. It's explained all very easily.
"The staging area lets you batch up your changes so you can issue multiple commands to add files, or get rid of them if you change your mind."
"Just use `git pull`. If you don't know why you need to `fetch`, don't do it. Git pull is just like an SVN checkout."
"When you commit, you don't have to send it to other people, so your work can be in a broken state, and you won't break it for everyone else. When you're super happy with it, use `push` and it'll be visible to everyone."
These explanations get people who understand SVN to get Git, and they understand exactly what Git is providing over SVN. Once I use these explanations, people never seem to have problems.
What seems to keep happening is they look on the Internet for solutions to issues, which tangles them up even further, with rebasing and such. Even the simpler tutorials like learn.github.com are obsessed with showing pictures of trees and different branching states that beginners simply shouldn't be exposed to. Their mental model is completely screwed up, and they start to blame Git (not unreasonably) rather than themselves. When SVN screw ups happen, they blame themselves because SVN is conceptually simple, so they know the mistake must have happened with them. Then I hear things like "This never happened with SVN" or "SVN was always so much easier". When I prod them about this, they do end up remembering that SVN had it's own issues, but they forget them when their current problem is Git.
EDIT: Oh, and the other problem is that some of the GUIs out there are criminally poor. Particularly eGit for Eclipse. It exposes a metric crapton of functionality that I have absolutely no idea about, and I've been using Git happily for two or three years now. I don't know about refs or anything, and eGit makes it all exposed and seriously painful to do anything. Having tried to help someone with it, I gave up. "I use the command-line. You think I use it because I am clever, but I use it because I am stupid. The command-line is much simpler than this car crash, and I have no idea how you have got as far as you have with it."
I've begun to think of engineer's ability to "get Git" as a sort of abstract-thinking FizzBuzz. DVCS breaks up some composite actions (svn commit/checkout) into their component parts (git fetch/merge/commit/push). If you can't make that mental leap and see the value in it (and accompanying tradeoffs) despite all the learning materials out there, how can you be expected to derive comparable evolutions of design and engineer on your own?
> Git allows the topic-branch development style, where you maintain one short-lived branch for every task you work on. Like many people, I learned about this style from distributed version control. I love it. It’s an excellent way to switch between tasks, and maps well to the way I actually think about the state of the project. But you don’t need Git to do this! Subversion has “svn switch”. It does have an annoying problem that if you specify the wrong URL to switch to, it will trash your local copy rather badly. However, Subversion seems to have fixed that problem in version 1.7.
Quite an annoying problem. I'm not really sure why the author is a git skeptic if it enables and introduced him or her to a wonderful workflow.
The ability to easily work on multiple branches and make offline commits is a huge selling point for any DVCS. I really like git rebase and git add -p now as direct arguments for git, but wouldn't have used them right away.
Edit: added clarification after quote
Perhaps because you can do the same thing in SVN?
At least, that's what he says. I don't really know SVN.
This is largely due to the fact that I have a strong aesthetic preference for languages where you can hold most of the language [1] in your head. Such languages are called compact [2].
[1] Compactness of language and standard library are different. Having a non-compact standard library isn't necessarily a bad thing, especially if it means I don't have to complicate my life with third-party libraries.
[2] http://www.catb.org/esr/writings/taoup/html/ch04s02.html
And, until (apparently) recently, if you make a mistake SVN will "trash your local copy rather badly" which isn't quite the same thing.
My work desktop is Red Hat, so I'm (unfortunately) used to downloading old versions of software...
Having a local repo and push/pull to any other repo is not a complication but a huge advantage. It lets you do things like commit while you are on an airplane, or share committed work in an internal team before pushing to trunk, or keep repo history even if the server dies in a fire. It lets you not have to worry about who can be trusted with commit permissions or not. Being able to commit all the time without pushing lets you keep revision history without checking in, so you don't end up with many copies of your working directories, or saving up changes before you are 'allowed' to commit.
Since you can commit all the time, you can destroy the working tree trying things out and then bring it back if they didn't work.
So let's not complain about having a working tree, local repo, or remote repo. The staging area makes it so that you don't have to complete all staging of many different files in one huge command. You can add/rm something, preview what's staged, and only commit when you are satisfied.
In addition, CVS type merge is a pain while it is actually much simpler with git or hg. And being able to keep rebasing your private feature branch on a changing remote branch is a huge improvement.
_The_ git repository is right there on your computer.
The OP says he is waiting for the git epiphany. The epiphany is that there is no _the_ remote repository. You can use git like it's subversion, and designate one repo as _the_ repo, but because git isn't designed this way it isn't going to help you much in this endeavour.
But underneath, the concepts are pretty simple, and because it's the right simple concepts, the things you can do with it are pretty flexible, and thus powerful.
Git's interface can defn be way better for the default case. But everyone and every team's workflow is different, so the inherent flexibility will always involve a little bit more complexity.
And oh, it seems that he hasn't yet discovered selective commits or stashing, so staging seems like an extraneous extra step.
And rewriting history seems frivolous if you work by yourself. But it makes pull-requests on open source projects way easier to manage if your commits are clean. And if you need to rollback to a working version of your production code, it helps to have clear commits too.
This is a BIG reason why I recommend even to advanced Gitsters to use a GUI tool like Tower or SourceTree so they don't get confused or inconsistent about how their repo is structured. I've used Git for years and I can't keep it all in my head. Surely some can but not me and probably not most.
Subversion got rid of those directories in version 1.7 (http://blogs.wandisco.com/2011/10/11/top-new-features-in-sub...)
Also, for the searching problem: betterthangrep.com. The reason I have perl installed on the Windows box at work.
"You can use “pull” to mean “fetch and merge”, but some authorities will advise you not to. You can also use “commit -a” to avoid the “add”, but you still have to be aware of it."
Whatever tutorial I originally used to learn Git made use of `git pull` and `git commit -a` exclusively, without any elaboration. It wasn't until long into my Git career that I was even aware of `git fetch` or `git add`. To this day I use `git add` only occasionally (but it's so useful when I do need to use it), and I honestly can't think of a case where I've needed `git fetch`.
I'm about to teach my co-workers to use Git for a project I'm spearheading, and I intend to expose them to this simplified view and let them fill in the blanks when needed.
His explanation was on the lines that if there are 100 developers working on different trees of freebsd and they want to commit their work, it causes a race, as if some one commits before you, you need to do a git pull, incorporate changes and then push, even when they are working on unrelated components.
My response to this was yes, and that is why git allows you to create branches so cheaply, but he still was not convinced.
My thoughts in this entire learning process was along the lines of - "Why the hell are they doing it like this, instead of that? Why are they calling this, like that, instead of just calling it what it already is?"
In my experience trying to learn GIT, I was able to conclude that GIT introduces a LOT of terminologies, and concepts, making the path for beginners like me more and more difficult. Whether spending hours learning these concepts just to get your stuff synced properly depends on your scenario. But for me, SVN rules.
Also, there is another REALLY brilliant way by which SVN helps me. I use Tortoise SVN. I have a couple of external 1tb hard-drives to back-up my code. I like to take regular backups (obviously) because some of the code is in production and I just want to play it safe. Using SVN, on windows, I run an SVN server on my machine, and create respective repo's on my hard-drives and just update them and voila - I have all the code properly backed-up and versioned. You can also automate this (there are scripts to do them), but for me, I like to keep it synced manually. And also, you can keep your stuff backed-up to your Google drive by making a repository inside your drive folder. I can't imagine typing all these as commands in GIT.
This makes some things easier. If the 'server' dies, you can substitute any other copy of the repository for the original. So if github disappears I can still continue to hack away on my code like usual (commit, branch, merge, etc), and if I decide to publish on gitorious or something later, then I just push my local repository up and everything is there (full history, etc). This sort of obviates the need for 'backups', since your copy is already a backup, but making extra backups of any repository is as trivial as copying it (rsync) or cloning it to somewhere else (cd /backup; git clone /myrepo) - so I don't need to run a server or anything to make backups.
As a thought experiment to illustrate the practical difference, consider why pull requests are so trivial to implement on github, and how would they work on the hypothetical svnhub?
So does Subversion, but you have already learned its terminology and concepts and are no longer a beginner.
This is the biggest issue I've always had with Git. I've struggled to understand why so many developers swear by a system that takes several steps backwards from other systems.
git add is never needed if you always git commit -a
if you don't care what git fetch && git merge does, just use git pull
The biggest problem with learning git is that all git experts love to talk about the advanced workflows, but all the beginners just want to be able to push and pull.
while git has submodules, they no way near have the flexibility of externals. if git would incorporate the idea of externals, I think it would cure quite a few people's complaints.
If you do an add, followed by a "git diff --cached", you can view what's going to be committed before you do the actual commit.
I've found this workflow to be useful, since it helps see things like debugging print statements that crept in, or unnecessary files accidentally added ("git diff --cached --stat" is useful for the latter).