

























Posted by on February 26, 2014
![]()
Credit:Tim Strater from Rotterdam, Nederland CC-BY-SA
Of all the well-documented difficulties I’ve had working with Git over the years, a few conceptual difficulties really stand out. They’re quirks in the Git architecture that took me far too long to realise, far too long to believe, or far too long to really grasp. And maybe you have the same problem without realising it.
git branch -d master
git checkout develop -b master
There, I did it. I’m now calling the develop branch master. What you call this branch, and what I call it, and what your Github repo calls it, and what my Github repo calls it just don’t matter. Four different names? No problem. There are some flimsy conventions that Git half-heartedly follows to link two branches with the same name, but it gives up pretty easily.
I have very frequently fallen into this trap:
$ git diff origin/master
$
No differences, so my branch must be in sync with Origin, right? Wrong. What is true is my branch is in sync with the local copy of Origin. If you don’t run git fetch, then Git will never even update its local copies.
Technically, Git has always been upfront about this. The Git book opens the section on remote branches:
Remote branches are references to the state of branches on your remote repositories.
But it’s counterintuitive, and so I keep messing it up. I keep hoping (and assuming) that Git will one day include an auto-fetch option, where it constantly synchronises remote branches
Here’s the message that we have seen many times:
Note: checking out ‘origin/develop’.
You are in ‘detached HEAD’ state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:git checkout -b new_branch_name
This scary looking message threw me off for a long time, despite the fact that it’s actually one of Git’s most helpful messages – it tells you everything you need to know.
It boils down to this: you can’t make a commit if you’re not at the top of a branch. The two most common situations that cause this are:
git checkout origin/develop -b mydevelop or even, if you want to abandon your branch completely:git branch -d develop
git checkout origin/develop -b develop
git checkout a8e6b18For a long time, I thought that ‘git init’, ‘git pull’ and ‘git clone’ somehow created repositories that were different, even if they ended up with the same commits in them. It’s hard to recreate my state of mind, but I spent a long time trying to salvage certain directories on disk when I should have just abandoned them.
Similarly, there is no difference between:
git clone http://github.com/stevage/myrepogit init
git remote add origin http://github.com/stevage/myrepo
git pull origin masterWell, in the second case Git’s a bit confused about which local branches map onto which remote branches, so you have to be more explicit or fix it with some configuration option.
For some reason, Git encourages you to call the source of the first clone “origin”. I have found this very confusing and ultimately very unhelpful. Let’s say you’re working on a project called widget, and you fork it in Github so you can work on it. You will want both remotes accessible locally, so you will probably do one of these:
git clone http://github.com/stevage/widget
git remote add widget http://github.com/widget/widgetgit clone http://github.com/widget/widget
git remote add mine http://github.com/stevage/widgetSo you either have remotes called “origin” and “widget”, or remotes called “origin” and “mine”. But on the next project, you might make the opposite choice, and soon you really don’t remember what “origin” means.
My tip: never name any remote “origin” ever. Name them all after their Github username.
git init
git remote add widget http://github.com/widget/widget
git remote add stevage http://github.com/stevage/widget
git fetch --all
get checkout stevage -b masterThe difference between “git reset”, “git reset –soft” and “git reset –hard” is beyond your comprehension. And you probably wanted “git checkout” anyway.
Rule of thumb:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。