Today, I would like to share some tips and tricks I've learned about Git. There are cases I meet often, and they gave me a better understanding of Git. It's certainly not a deep coverage of the topic, but it could help you as it helped me. Enjoy!
How to track an existing remote branch?
First of all, you can inspect the remote to check which branches are untracked
git remote show origin
The untracked branches are listed below "New remote branches". You need to fetch in order to store them in remotes/origin.
Finally, you explicitly track the remote branch by doing
git checkout -t origin/remote-name
If you want to set it up with another name, you’ll rather do
git checkout -b local-name origin/remote-name
How to clone a private Github repository without prompting username and password?
The typical use case is when the clone is triggered by another software and you just have the username and password (and no SSH keys). To do that, you can use the HTTPS URI including the authentication information as following:
git clone https://username:email@example.com/id/repo
Notice that if you want to use your SSH key, you have to use the ssh URL or the scp-like format.
How to migrate a repository from Subversion to Git?
I'm talking here about the case of one-shot migration, not a mirror. It exists tool to set up a Git mirror of a Subversion repository.
First, retrieve a full dump of your Subversion repository
svnadmin dump /server/pathto/repo > full.dump
If you don't have directly access to the repository directory, you can use svnsync if you have the necessary credentials to remotely access to it.
Second, load your dump into a local repository (you can skip that step if you've replicated your repository with svnsync):
svnadmin create /local/pathto/repo svn admin load /local/pathto/repo < full.dump
Third, import your Subversion repository into a Git one
git svn clone file:///local/pathto/repo /local/pathto/git-repo -no-metadata -T trunk
If you want also import the tags and the branches, you can do the following (but beware, it will drastically increase the import time if you have a lot of them)
git svn clone file:///local/pathto/repo /local/pathto/git-repo -no-metadata -t tags -b branches -T trunk
If you want to map your Subversion users to Git ones, you can create a text file in which each line defines a mapping with the following format:
svn-username = Firstname Lastname <firstname.lastname@example.org>
Then, you just have to provide that file, for instance users.txt, while importing from SVN to Git:
git svn clone file:///local/pathto/repo /local/pathto/git-repo -no-metadata -A users.txt -T trunk
How to count the number of change sets?
You can log all change sets with an empty line with the following:
git log --pretty=format:''
After you just need to count the lines with some pipe and bash:
git log --pretty=format:'' | wc -l
How to cancel a commit or a staging?
Before answering that question, I need to get back to the Git workflow through working tree, index, and commit areas.
When you're working on tracked files, you make changes, you're working into the working tree. When you add your changes, you put them in the staging area for commits or the index. When you commit the staged changes, you froze those changes into the commit area. The changes set is stored in the repository graph and indexed with a SHA.
Put back changes to index
So let say you've just committed a change you made in a file. You have then the following situation in terms of commits graph:
But you want to cancel and put it back in staging area (index), you do:
git reset --soft HEAD^
and you have then
with all your changes still in the staging area.
Remove changes from index
If then you want to remove those changes from the staging area, you can do:
git reset HEAD
If you want to do the both steps in one, you can do
git reset HEAD^
In both cases, you don't destroy the commit C, you've just moved the HEAD pointer. That means you can go back to C by doing
git checkout C
Cancel and destroy a commit and all local changes
When you cancel a commit, if you also want to destroy it, you can do a hard reset:
git reset --hard
That one also modifies your working tree and index as it gets rid of all local changes.
If you have any other tips related to those, please tell me. Same if I make any mistake.
Can also discuss that post on Hacker News