Git Usage
Table of Contents
- Initialization
- Branch
- Tag
- Submodule
- Pull
- Fix untracked files
- How to undo the most recent commits
- Resolve a merge conflict using the command line
- Remove all history commits
- Integrate commit and push into one command
- Restore the deleted file
- Refuse to Merge Unrelated Histories
- Git Clone with Specific Port
- Move Files When Checkout a New Branch without Commit or Merge
- Use Git over a Proxy
- Update Logs
Git is an awesome tool for version control. I used to some convenient GUI applications to manage git repository, and ignored how it works and how to do it by command line. So in this article I will record some useful git commands that I used in development.
Initialization
Initialize a local git repository
git init
# recommand the way using ssh
git remote add origin ssh@xxxx
Push to remote repository
git add .
git commit -a
git push origin master
Pull from remote repository
git pull origin master
List the available remote repositories
git remote -v
Branch
Create
# create a branch named "branch1"
git checkout -b branch1
Checkout (from local)
git checkout master
Checkout (from remote to local)
git checkout -b branch1 origin/branch1
Merge
# assume you are in master branch and want to merge the code from hotfix
git merge hotfix
Rename
# rename
git branch -m old-name new-name
# Delete the old-name remote branch and push the new-name local branch.
git push origin :old-name new-name
# Reset the upstream branch for the new-name local branch.
git push origin -u new-name
Delete local Branch
git branch -d branch_name
# force delete
git branch -D branch_name
Delete remote branch (remote name: origin, remote branch: branch1)
git push origin --delete branch1
Tag
Create
# add tag(e.g. v1.0) for current branch
git tag v1.0
# add tag with commit id(e.g. 039bf8b)
git tag v1.0 039bf8b
# add tag with extra message
git tag -a v1.0 -m "version 1.0"
View
# view local tags
git tag
# view remote tags
git ls-remote --tags
Share the Tags
# push a specific tag
git push origin v1.0
# push all local tags for one time
git push origin --tags
Switch
git checkout v1.0
Delete remote tag(e.g. v1.0)
git push -d origin v1.0
Submodule
Init all submodules.
git submodule update --recursive --init
Update all submodules.
git submodule update --recursive --remote
Reset all submodules.
git submodule foreach git reset --hard
Pull
Pull forcely.
git reset --hard origin/master
git pull
Fix untracked files
For example, although you added some files into .gitignore, those are still tracked by git. The solution of the problem shown in below:
git rm -r --cached .
git add .
git commit -m "fixed untracked files"
How to undo the most recent commits
The more details could be found in StackoverFlow.
# your files will not lose, even index not too
# you can simply recommit again
git reset --soft HEAD~
git commit -a -m "recommit"
# reset with "--hard" would switchs the previous state entirely
# that means this not leaves your files and index both
git reset --hear HEAD~
Resolve a merge conflict using the command line
The more details could be found in Github Documents.
git status
# >>> OUTPUTS OF git status <<<
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
# (use "git merge --abort" to abort the merge)
#
# Changes to be committed:
#
# new file: socket_learning/class3/__init__.py
# new file: socket_learning/class3/db/Message.txt
# new file: socket_learning/class3/db/User.txt
# new file: socket_learning/class3/models/message.py
# new file: socket_learning/class3/models/user.py
#
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# deleted by us: socket_learning/class3/models/__init__.py
# added by us: socket_learning/server_impl/models/__init__.py
# both modified: socket_learning/server_impl/routes.py
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# socket_learning/__pycache__/
# socket_learning/server_impl/__pycache__/
delete by us
and added by us
can be added or deleted simply using the following command.
git add <file>
git rm <file>
both modified
should manually merge using the text editor, like Vim or Atom. In these case, the conflict of routes.py
is showing as below
<<<<<<< HEAD:socket_learning/server_impl/routes.py
from socket_learning.server_impl.models.message import Message
from socket_learning.server_impl.models.user import User
from socket_learning.server_impl.utils import log
=======
from socket_learning.class3.models.message import Message
from socket_learning.class3.models.user import User
from socket_learning.class3.utils import log
>>>>>>> d8a8b9b8ad0e55b7216520600ae1bf809b5b2aa7:socket_learning/class3/routes.py
<<<<<<<
, =======
and >>>>>>>
indicates the places where conflict occurred, you should determine what the contents is the right one and change it with text editor.
# handle the conflicts manually
from socket_learning.server_impl.models.message import Message
from socket_learning.server_impl.models.user import User
from socket_learning.server_impl.utils import log
Save it and recommit them.
git add .
git commit -a -m "Merge branch 'master' of github.com:xavier-niu/python-playground"
Remove all history commits
Checkout
# the core use for "git checkout --orphan" is to reach
# a "git init"-like situation on a non-new repository
git checkout --orphan latest_branch
Add all the files
git add -A
Commit the changes
git commit -am "commit message"
Delete the master branch (or what branch you want to clean)
git branch -D master
Rename the current branch to master
git branch -m master
Finally, force update your repository
git push -f origin master
Integrate commit and push into one command
This not supports by the build-in git command. But we can add a customized function into .bash_profile
(for mac) to implement it.
# lazygit for using commit and push in one command
# usage: lazygit "commit msg"
function lazygit() {
git add .
git commit -am "$1"
git push
}
Restore the deleted file
Assume that test.txt
is the file you want to restore. First of all, find the last commit that affected the given path.
git rev-list -n 1 HEAD -- test.txt
# outputs: 145107deebdbbad4ce0824b0dbb6f648b5515de7
The outputs are the id of the last commit. Checkout the version at the commit before, using the caret symbol.
git checkout 145107deebdbbad4ce0824b0dbb6f648b5515de7^ -- text.txt
Or in one command
git checkout $(get rev-list -n 1 HEAD -- text.txt)^ -- text.txt
Refuse to Merge Unrelated Histories
Git reports an error when pulling from remote source.
XavierNius-iMac:lucius-dev xavierniu$ git pull origin master
From github.com:xavier-niu/docker-lucius
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
The following command with --allow-unrelated-histories
is work.
git pull origin master --allow-unrelated-histories
Git Clone with Specific Port
The git clone command with default port is
git clone git@localhost:root/lucius.git
Assume that the port is 1923, the command is switch to
git clone ssh://git@@localhost:1923/root/lucius.git
What we added:
- ssh protocol at the beginning of address
- the port you specified behind the colon
Move Files When Checkout a New Branch without Commit or Merge
Sometimes, I often forget to checkout a new branch when composing a new module. Therefore, I don't want to commit it, neither want to merge it, but only would like to save current status and change the branch in that I haven't reached the milestone. To achieve it, I recommend to use stash
command.
# step 1
git stash
# step 2: checkout
git checkout new-branch
# step 3: restore current status
git stash pop
Use Git over a Proxy
Assume that there is a proxy like 127.0.0.1:1080
, both http and ssh proxy should be configed to ensure we can access the remote resources through any ways, like ssh protocol.
# git http proxy
git config --global http.proxy socks5://127.0.0.1:1080
Add the following lines into ~/.ssh/config
, this method is passed on the macOS, other OS I haven't test.
Host github.com
ProxyCommand nc -X connect -x 127.0.0.1:1081 %h %p
ServerAliveInterval 10m
BTW, in the git http proxy config, you should use socks proxy with the "socks5://" prefix, on the contrary, in the ssh config, you should use http proxy.
Update Logs
This post will be updated continuously with my development. There are the logs to better know when I updated those contents:
- January 20, 2019:
init
move all contents from Notion to my blog - January 21, 2019:
add
remove all history commits - January 22, 2019:
add
branch > delete remote branchupdate
tag > createadd
tag > delete remote tagupdate
tag > share the tagsupdate
tag > view
- January 27, 2019:
add
integrate commit and push into one command - February 3, 2019:
add
restore the deleted file - February 27, 2019:
add
refuse to merge unrelated histories - March 8, 2019:
add
git clone with specific port - March 17, 2019:
add
move files ehen checkout a new branch without commit or merge - April 4, 2019:
add
use git over a proxy