What git gotchas have you been caught by?
The worst one I've been caught by was with git submod开发者_开发知识库ules. I had a submodule for a project on github. The project was unmaintained, and I wanted to submit patches, but couldn't, so I forked. Now the submodule was pointing at the original library, and I needed it to point at the fork instead. So I deleted the old submodule and replaced it with a submodule for the new project in the same commit. Turns out that this broke everyone else's repositories. I'm still not sure what the correct way of handling this situation is, but I ended up deleting the submodule, having everyone pull and update, and then I created the new submodule, and had everyone pull and update again. It took the better portion of a day to figure that out.
What have other people done to accidentally screw up git repositories in non-obvious ways, and how did you resolve it?
The usual trailing slash when adding a submodule:
When you use git add on a submodule, make sure you don’t have a tailing slash.
> git add local/path
-- adds the submodule
> git add local/path/
-- adds all the files in the submodule directly into your repository, big no-no
It's not a gotcha, it's a gitcha.
Publishing to public repository without realizing my git config user.name
was incorrect.
That means the public repo now gets a name (and an email) I would rather not have published at all. If that repo is replicated, ... it is too late.
That is why I prefer having my user.name displayed in my git prompt shell, meaning instead of having this:
MY_HOSTNAME /c/Prog/myGitProject (master)$
I see this:
MY_HOSTNAME /c/Prog/myGitProject (master) VonC $
I know who I am from the very first command I type in this Git bash session!
Only realising you've forgotten an entry in
.gitignore
once you've got matches spread across a load of branches.Forgetting that git add doesn't add what's not there...
git add . git commit git status //hey! why didn't it commit my deletes?, Oh yeah, silly me git add -u git commit --amend
- If you do a
git branch list
, you get a new branch calledlist
, but if you do agit stash
, you get your workspace stashed; for stash, you need thelist
if you want the list...
More soon, probably...
- Work work work
- Stash changes
- Fetch latest
- Rebase
- Get conflicts, fix them
- Forget to "git rebase --continue"
- Pop stash
- Realize I forgot to "git rebase --continue"
- git rebase --abort
- Changes I stashed originally - pfffft, gone.
Work work work ...
git commit
Work work work ...
git commit
Hm... time to integrate
git rebase -i origin/master
What? Conflicts? Let's start again
git reset --hard origin/master
Cry cry cry...
Git lets you wipe your local history without remorse. The biggest gotcha is that you are the safety net.
One of my most embarrassing moments with a git repository, though it's more about sed:
I was once doing a find ... -exec sed -i ...
operation in a subdirectory of my repository. I'd tested it without the -i
first, got distracted, came back and managed to switch to the top directory in my repo before running it. Now, git's important files are all read-only, but sed -i
by default shuffles the file away by renaming then writes back to the original, so it works just fine on a read-only file like git's objects. The substitution wasn't reversible, and I had to recover the repository by cloning and fetching from someone who tracked mine as a remote.
I never even thought for a moment that sed would work on read-only files. Moral of the story: use sed -i -c
, which copies the file, then attempts to overwrite the original.
Create a new branch:
git branch new-branch
Work, commit, work ... Realise all my work is on master, not on the new branch.
I should have done:
git checkout -b new-branch
Why can't I do something like:
git branch -c new-branch
(c for checkout) with an option to make that the default behaviour???
Work work work. Start staging a change. Notice you don't want everything committed. Stage a partial commit carefully.
Eventually decide that this isn't ready for the current branch. I want to commit the staged changes to a new temporary branch. Sounds so trivial conceptually, right?
Google for how to do this. Top answer says stash
, checkout -b newbranch
, stash pop
. Do this begrudgingly, wondering why there isn't an easier way.
Find that this completely wiped the distinction between your staged and unstaged changes. Thanks, Git!
精彩评论