It's possible to build a very successful git workflow using only the following commands:
git clone git:...
git add path/to/new_file
git commit -a
If you want to use branches, you need to add:
# Showing branches.
git branch -a
# Checking out branches.
git checkout some_branch
# Creating and pushing a new branch.
git checkout -b new_branch_name
git push -u origin new_branch_name
# Checking out an existing branch.
git checkout -b some_branch origin/some_branch
# Merging a branch into your current branch.
git pull origin some_branch
But if you start digging around under the hood, and you start editing your commit history, you'd better be prepared to understand what you're trying to do.
Trying to use rebase the same week or month that you learn git (or version control period), while doable for some, is just crazy for everyone else. You don't jump into riding a bike before you learn to walk.
If you do a "git status" immediately before then "git commit -a" can be a slight time saver; though It's better to use "git add -u", which stages all files that are in the repo and ignores any new files. Personally, I like adding files either 1 or 2 at a time or even with "git add -p".
While I'm at it, lots of people seem to have poor (single line) commit messages, stemming from the use of "git commit -m". Whilst this is OK on some occasions, commit messages are often better thought of as an email with a subject and a body.
(Yes, I know sometimes a single line commit is all you need and you can write multi-line commits directly on your shell but some people don't know this and it limits their ability to write a good commit message.)
Feel better getting that out my system. Now I need to tell my co-workers.
That said, reading through a bunch of fine-grained and uninformative merge commits when looking at a log is really annoying. Serious projects expect submissions to be in the form of clean patch sets that apply in series and "look like" an instantaneous change. No one cares about per-developer histories.
If you look at the kernel history, for example, the only merge commits you see are Linus's and the subsystem maintainers'.
Frankly, git was not designed for a lot of the use cases it's finding itself in. Medium sized agile teams (5-10 devs) with multiple people mucking around in the same files will be removing bullets from their feet repeatedly for a few weeks when first switching.... OR they will have an incomprensible tangle of branches and merge commits that no person will ever be able to figure out.
Git by default shows this stuff, which in the kernel's use case is useful data. But in this case it's just useless chaff, and an annoyance. But hardly a serious problem.
This workflow actually works pretty well with your desired outcome as well - you can rebase your local branch against newly pulled changes on master. This will make all of your local branch merges look like fast forward merges on master (i.e. no merge commit, linear history).
- Create a feature branch off of development.
- Commit lots of times until that's ready.
- Switch back to development. Do "git merge --squash featurebranch" This introduces all the changes from the feature branch as uncommitted changes. View the diff to ensure it's exactly what I wanted, and commit them with a single, coherent commit message.
Undoing a commit, for example, is very common and necessary, especially for beginners.
Sure, you can edit the broken commit, if you value a pretty commit history. But again, this requires understanding git well enough to predict the effects. What happens if you run 'git commit --amend -a' after pushing the original commit? What if another user already pulled? How will you fix the resulting mess?
If you can answer these questions, then you'll have no problems editing history. If you can't, then you may be signing up for a lot of pain.
# Oh no! Those changes should have been on their own branch, not dev...
git checkout -b changes_on_their_own_branch
git stash apply
git commit -a
git checkout -b changes_on_their_own_branch
git commit -a
On the other hand, stashing may be required if you wanted your branch to start elsewhere:
git checkout -b changes_branch start_point
In other words, no harm in trying the `git checkout other_branch` first, and only stashing if that fails.
For every branch that is up to date or successfully pushed, add upstr
eam (tracking) reference, used by argument-less git-pull(1) and other
commands. For more information, see branch.<name>.merge in git-config
Git will deduplicate all of your binaries across branches (and if you are clever, across repositories, but that's another story) so worst case you will only have one copy of any binary file no matter how many times it appears in your history.
That is not to say that git may be a poor fit for your current project+organization for other reasons but a blanket assumption of ("repository would be too huge") is not generally accurate.
The binaries are already deduped, that's why they live in svn.
Had the statement been: "Our SVN repo is alreay 100s of GBs in size" then yes you are not likely to want to stuff that onto a laptop but that was not the claim. The claim (without rationale) was that the git equivalent would be 100s of GBs which is similar but not at all the same.
one assumse 1:1ish correspondence the other applies an unstated multiplier SVN * n = git where n > 1 (and significantly so.)
In reality the multiplier appears to be negative in many cases:
> Git's repositories are much smaller than Subversions(sic) (for the Mozilla project, 30x smaller) 
Mozilla's ratio would be relevant if they were storing something like the visual studio installer in their repo. They aren't, so it's not.
Of course, such algorithms do exist - Google's Courgette - but I don't think git is using them (I have looked) and doubt they are tuned to e.g. Borland TDS/RSM/etc. symbols.
I have no idea how large the svn repository is - it's stored on a SAN and run on a dedicated server I only interact with via svn. It could be many terabytes for all I know; and of course, my team's project tree isn't the only thing in the full repository.
Still optimistic? :)
I'd also recommend The Git Parable (http://tom.preston-werner.com/2009/05/19/the-git-parable.htm...) for anyone who hasn't read it. Different focus, but also helpful for understanding git's philosophy.
git merge master
git branch master
Branching and merging is covered pretty well by Pro Git
To do what you are describing you would do this (or something similar:
git checkout master; git merge experimental
The merge command then takes the commits in experimental that aren't in master and puts them into master.
git branch [some name]
You can do some things to make it easier on yourself (and others) but it's not simple. You find out how un-simple it is when you hit one of those magical corner cases.
Don't get me wrong, I love Git. I far prefer it over SVN and CVS. But it's not simple.
The point of this article is that if you take the time to learn how git is actually constructed, the CLI becomes a lot more bearable, and is less likely to leave you in distress when Something Unexpected Happens.
The fact that the contents of the .git folder can be explained in ~2000 words (10 min of reading) is impressive--this would be impossible with a more complicated data model.
All the results for the svn search are about getting rid of these folders -- nothing explaining their contents.
That would be because there's little to no content in the svn folders, and none of it is user-consumable: all the metadata manipulation is done via svn's properties and their cli interface (proplist, propset, propget and propdel).
Apart from these, the content of the .svn folders (at least before 1.5) is pretty much only duplicates of your checked-out files. All the brains live in the (remote) repository, not in the .svn folders. I've never seen any case where somebody would go muck around with the content of the .svn repos, the only direct manipulation of them users have a use for is stripping them for exports or because somebody did not `svn export` and sent .svn folders where they did not belong.
Oh, and svn has had a full-featured client library (and bindings for most popular languages) for a very long time, so people have rarely needed to essentially reverse-engineer the interaction process from a checked-out working copy.
edit: now that I think about it further, your very observation is proving the complexity of git, or at least of git's UI: it's not expected that users of svn ever go muck around with their .svn (and as I explained there really is no reason to), so there is no wondering or audience about that, whereas not only is it expected that git users understand the content of their .git, it's pretty likely it will become necessary at one point in your usage of git, because you'll have no other way (learning the plumbing by rote is not an option until you've even done that, since it can only be understood if you know how git's store works, you'll just end up learning both anyway)
Have you tried Tower (http://www.git-tower.com/)? I used it briefly for a small project and thought it was nice, but didn't really have time to get to know it that well.
Because it's simple bash scripts but distributed and decentralised it has a steep learning curve.
No, no git is not simple. It's really complicated.
[~] 0 (jon@snowball2)
$ file /usr/lib/git-core/git-status
/usr/lib/git-core/git-status: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, stripped
From the mercurial docs: "If you felt uncomfortable dealing with Git's index, you are switching for the better."
To be honest, after a few years with git, I feel uncomfortable without the index.
Is it too late for an improved git user experience? With so many online tutorials and books, a new porcelain interface would have a tough time capturing much mind share (while still calling itself git).
For those looking for something simpler than git, I recommend eg (EasyGit), a one-file Perl wrapper:
(or maybe the author did mention it and I missed it?)
Another fallacy is that "writing code" is the only "useful" thing one can do. Creating clean logical history and good commit messages (or other documentation) does not invole writing code, but that doesn't mean it is not important.
The point I was trying to make is that tools are productivity aids and if a tool gets in the way and distracts you from your main activity (or activities) too much it can be counter productive.
I use both Eclipse and VisualStudio and find those tremendous! A good tool hides unnecessary stuff from you and works in a clear predictable way. A tool is bad for me when it does the opposite.
In my experience, once you understand how git works it gets out of your way entirely.
Would that be very different from what git is now? My underbelly says yes, but really I'm not knowledgeable enough to tell. Any ideas?
I remember when I was migrating from CVS to git, it's ok to understand cvs update is git fetch & git merge now, committing is the same, additionally I need to push the commits to share with co-workers. The hardest part to understand rebasing and branch management. But it worth to learn all these concepts, it make version control more flexible. It's pretty cool to use git reset and git push -f to modify the commits history (make sure you know what you are doing).
Spot on! I really thought I was the only one.
Oh no! I now see cognitive dissonance everywhere. I realized that it's the same with git: maybe we like it so much because it took such a hard time to master. I still don't feel like I master it. However, reading some books on git and understanding the philosophy did make it feel simpler.
I think the intended audience of the article are people who are already at least vaguely familiar with Git, but do not know its inner workings. The thesis seems to be "Git is complex, but not as complex as you might fear reading 'man git'".
1. Resolve the conflict and continue rebasing.
2. Drop the conflicting change and continue rebasing.
3. Abort the rebase operation.
I ADORE git and can't imagine NOT using it now that I've switched, but the little sentence above packs a whole lotta lame in it.
Executive decision? Gross. There are good reasons for them, but not many. If you can't win your team over you probably don't have a good argument for the change... which brings me to the next problem I have with that sentence: winning the Internet? That's a great reason to look into something. Not a great reason to switch your team to it.
Also, no. It's not simpler. It's pretty much just as complicated as You think it is. It's actually kind of a big pain in the ass to start using git.. but boy is it worth it.
Better to keep up while the team is small than to try to move even more people over later and turn into mega-corp still using CVS.
Learning something new isn't necessarily a bad thing. I question people that are unable to try to learn something new every day. It takes a few minutes of your time and you can learn something. Sure, git might take more than a few minutes… but why not TRY?
As for requesting why they switched from subversion to git… yea, as I said, you have a billion articles written out there by now about WHY. There aren't more needed. The benefits are pretty clear if you read any one of those other articles.
Of course, this more leads into "why git and not mercurial (or any other DVCS)?" Which again, has a billion other articles written up on it.
And, yeah, he warns you about rebase.
Once you understand the internals -- I remember being amazed at what .git/objects/ really was -- nearly everything about the git ecosystem becomes measurably easier to understand.
Once you understand how your project looks in the eyes of git, it becomes a breeze to manage.