This is a post summarizing some common functionalities of Github that I run into often.
- create a new repository
- squash vs pick (git rebase -i commitxxx)
- rebase vs merge
- git ignore
- git amend
- git stash
- renaming a remote
In general, I highly recommand this website
Create a new repository
Approach 1 (start from no git repository)
create a repository online first, and then get the url. Follow a series of commands like “git init, … set remote origin ….” [the series of commands should be displayed online.
then git add everything and push to origin
Approach 2 (start from an existing git repository)
create a repository online first, and then simply set the remote url “git remote set-url origin xxx”
then git add everything and push to origin
Squash versus Pick
My specific use case was that I accidentally added a very big file that I don’t want to upload to the remote repository in commit x. Now, in commit x+1, I try to remove the file. However, the way commits are uploaded, it will still try to upload by performing commit x first.
git rebase -i and replace “pick” on the second and subsequent commits with “squash” or “fixup”, as described in the manual.
In this example,
is commit X+1 i.e. parent of the oldest commit you want to squash.
To do this, you first enter the interactive mode as detailed in the following link (-i is the key to interactive)
The key is here
If you want to fold two or more commits into one, replace the command “pick” for the second and subsequent commits with “squash” or “fixup”.
rebase vs merge
There is a debate between what should we use when merging updates from a different branch. Merging allows non-destructive
merge is a simpler command, but it can result in a messy project history.
rebase gives a cleaner project history, but can be a bit harder to master. It is also a bad idea to do git rebase on a public branch, as it will diverge the branch history. (Hence, the Golden Rule of git Rebase)
Setting up a good git ignore file is very important because it can prevent problems of uploading unintended files. For example, .pdf files in latex repositories,
To do this,
simply create a .gitignore file in the root directory of the git repository, and put the pattern in there,
*.pdf in there, then if you try to do
git add xx.pdf,
you will see
“The following paths are ignored by one of your .gitignore files:
Use -f if you really want to add them.”
You can find good documentation and a sample git ignore file here
A typical gitignore file for Latex repository for example is shown here,
Another technique for rewriting the history of the repository. This one specifically targets modifying the last commit. It is effectually replacing the last commit with the new commit.
This is useful if you realized immediately that you made a mistake in the last commit, added a big file or something. Amend will just cancel out the last commit.
A more comprehensive documentation can be found here
git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the
git remote rename xxx yyy
To see what branches are available in the remote
To edit a branch locally, you need to track a
git merge branch
git merges branch with the current branch.
UseCase1: This is often useful when there is a “master” branch and “dev” branch. When you want to integrate the latest changes in “master” into “dev”, you would first “git checkout dev” to go into “dev” branch, and then do “git merge master” to merge master into dev.
UseCase2: When you want to apply a hot fix into master branch. You can first create the branch “hotfix” and apply the change to it. Then switch back to master branch, and then do “git merge hotfix” to merge hotfix into master. The full example is shown here
(Notice that the <- error means “after” not “before” in the tutorial above).
git pull is actually a combination of two commands, “git fetch” and “git merge FETCH_HEAD”.
FETCH_HEAD is the tip of the remote fetch specified.
As a result, when you do “git pull origin master” in “dev” branch, you automatically merged the updates from master into the current branch.