Git
git is a version control system for tracking changes in source code during software development processes.
Getting Started
Create a Repository
Create a new local repository
$ git init [project name]
Clone a repository
$ git clone git_url
Clone a repository into a specified directory
$ git clone git_url my_directory
Make a change
Show modified files in working directory, staged for your next commit
$ git status
Stages the file, ready for commit
$ git add [file]
Stage all changed files, ready for commit
$ git add .
Commit all staged files to versioned history
$ git commit -m "commit message"
Commit all your tracked files to versioned history
$ git commit -am "commit message"
Unstages file, keeping the file changes
$ git reset [file]
Revert everything to the last commit
$ git reset --hard
Diff of what is changed but not staged
$ git diff
Diff of what is staged but not yet commited
$ git diff --staged
Apply any commits of current branch ahead of specified one
$ git rebase [branch]
Configuration
Set the name that will be attached to your commits and tags
$ git config --global user.name "name"
Set an email address that will be attached to your commits and tags
$ git config --global user.email "email"
Enable some colorization of Git output
$ git config --global color.ui auto
Edit the global configuration file in a text editor
$ git config --global --edit
Working with Branches
List all local branches
$ git branch
List all branches, local and remote
$ git branch -av
Switch to a branch, my_branch, and update working directory
$ git checkout my_branch
Create a new branch called new_branch
$ git branch new_branch
Delete the branch called my_branch
$ git branch -d my_branch
Merge branchA into branchB
$ git checkout branchB
$ git merge branchA
Tag the current commit
$ git tag my_tag
Observe your Repository
Show the commit history for the currently active branch
$ git log
Show the commits on branchA that are not on branchB
$ git log branchB..branchA
Show the commits that changed file, even across renames
$ git log --follow [file]
Show the diff of what is in branchA that is not in branchB
$ git diff branchB...branchA
Show any object in Git in human-readable format
$ git show [SHA]
Synchronize
Fetch down all the branches from that Git remote
$ git fetch [alias]
Merge a remote branch into your current branch to bring it up to date
$ git merge [alias]/[branch]
Transmit local branch commits to the remote repository branch
$ git push [alias] [branch]
Fetch and merge any commits from the tracking remote branch
$ git pull
Merge just one specific commit from another branch to your current branch
$ git cherry-pick [commit_id]
Remote
Add a git URL as an alias
$ git remote add [alias] [url]
Show the names of the remote repositories you’ve set up
$ git remote
Show the names and URLs of the remote repositories
$ git remote -v
Remove a remote repository
$ git remote rm [remote repo name]
Change the URL of the git repo
$ git remote set-url origin [git_url]
Temporary Commits
Save modified and staged changes
$ git stash
List stack-order of stashed file changes
$ git stash list
Write working from top of stash stack
$ git stash pop
Discard the changes from top of stash stack
$ git stash drop
Tracking path Changes
Delete the file from project and stage the removal for commit
$ git rm [file]
Change an existing file path and stage the move
$ git mv [existing-path] [new-path]
Show all commit logs with indication of any paths that moved
$ git log --stat -M
Ignoring Files
/logs/*
!logs/.gitkeep
# Ignore Mac system files
.DS_store
# Ignore node_modules folder
node_modules
# Ignore SASS config files
.sass-cache
A .gitignore
file specifies intentionally untracked files that Git should ignore
Tricks
Rename branch
- Renamed to
new_name
$ git branch -m
- Push and reset
$ git push origin -u
- Delete remote branch
$ git push origin --delete
Log
Search change by content
$ git log -S''
Show changes over time for specific file
$ git log -p <file_name>
Print out a cool visualization of your log
$ git log --pretty=oneline --graph --decorate --all
Branch
List all branches and their upstreams
$ git branch -vv
Quickly switch to the previous branch
$ git checkout -
Get only remote branches
$ git branch -r
Checkout a single file from another branch
$ git checkout --
Commit
Rewrite last commit message
$ git commit -v --amend
Git Aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
See also: More Aliases
Set up the server
添加 git 用户
sudo adduser git
配置 SSH-Key 登录
scp ~/.ssh/id_rsa.pub [email protected]:~/lsong-key.pub
ssh [email protected]
...
mkdir /home/git/.ssh
cat lsong-key.pub >> .ssh/authorized_keys
sudo chown -R git:git /home/git/.ssh
sudo chmod 700 !$
sudo chmod 600 /home/git/.ssh/*
现在应该可以在本地通过 git
用户登录服务器了
开始一个项目
在服务器上启动一个项目
cd ~git/
mkdir project.git
cd project.git
git --bare init
在本地开始这个项目
cd myproject
git init
git add .
git commit -m 'initial commit'
git remote add origin [email protected]:project.git
git push origin master
你也可以 clone
这个项目
git clone [email protected]:project.git
权限控制
读写权限
让需要 git
服务写权限的用户将 SSH 公钥发给你
cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L
ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k
Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez
Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv
O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq
dAv8JggJICUvax2T9va5 gsg-keypair
然后你需要
cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
这个用户就可以提交了
只读权限
cd ~git/public_html
ln -s ../project.git project.git
要开启需要
cd project.git
mv hooks/post-update.sample ./hooks/post-update
chmod a+x ./hooks/post-update
./hooks/post-update
任何人都可以通过
git clone https://lsong.org/~git/project.git
来 clone
项目
安全性
你可以用 Git 自带的 git-shell
工具限制 git
用户的活动范围。只要把它设为 git
用户登入的 shell,那么该用户就无法使用普通的 bash 或者 csh 什么的 shell 程序。编辑 /etc/passwd
文件:
sudo vim /etc/passwd
在文件末尾,你应该能找到类似这样的行:
git:x:1000:1000::/home/git:/bin/sh
把 bin/sh 改为 /usr/bin/git-shell (或者用 which git-shell
查看它的实际安装路径)。该行修改后的样子如下:
git:x:1000:1000::/home/git:/usr/bin/git-shell
现在 git
用户只能用 SSH 连接来推送和获取 Git 仓库,而不能直接使用主机 shell。尝试普通 SSH 登录的话,会看到下面这样的拒绝信息:
$ ssh git@gitserver
fatal: What do you think I am? A shell?
Connection to gitserver closed.