install
server
1
2
3
4
|
# download and install
yum install -y git
# create a git user
sudo adduser git
|
client
1
2
3
4
5
|
# download and install
yum install -y git
# 国内替换 github 镜像
# 使用国内镜像,目前已知Github国内镜像网站有github.com.cnpmjs.org和git.sdut.me
git config --global url."https://github.com.cnpmjs.org/".insteadOf https://github.com/
|
config
git config 配置级别
级别 |
参数 |
对应文件 |
system 级别, 所有用户生效 |
–system |
[Mac] /usr/local/etc/gitconfig [linux] /etc/gitconfig |
对单个用户生效 |
–global |
~/.gitconfig |
相关命令
1
2
3
4
|
# 查看 git 用户配置, 当 pwd 为 git 目录时,额外显示 pwd 的 git 信息
git config --list
# 编辑文件
git config --global --edit
|
remote url 使用 HTTP 时,记录密码
1
|
git config --global credential.helper store
|
显示中文
1
|
git config --global core.quotepath false
|
URL 替换
1
2
|
# 使用 https://github.com.cnpmjs.org/ 替换 https://github.com/
git config --global url."https://github.com.cnpmjs.org/".insteadOf https://github.com/
|
概念解释
常用流程
搭建 git 服务器
1
2
3
4
5
6
7
8
9
10
11
12
|
adduser git
# 禁止 git 用户使用 shell 登录
vim /etc/passwd
git:x:1000:1000::/home/git:/bin/git-shell
# 初始化 git 的 ssh
su git
cd /home/git
mkdir .ssh
cd /home/git/.ssh
touch authorized_keys
chmod 700 /home/git/.ssh/
chmod 600 /home/git/.ssh/authorized_keys
|
添加授权用户至 git 服务器
1
2
3
4
5
|
# 本地生成ssh-key, 默认情况下生成256位的 ssh-key 至本机的~/.ssh 目录下,其中id_rsa 为秘钥,id_rsa.pub 为公钥
ssh-keygen
# 添加公钥 id_rsa.pub 的内容追加到服务器下
pbcopy < ~/.ssh/id_rsa.pub
echo '$'>> /home/git/.ssh/authorized_keys
|
本地仓库初始化
1
2
3
4
5
6
|
git init & vim .gitignore
git add ./ & git status -s
git commit -m "init"
git remote add origin ssh://[user]@[ip]/usr/local/git/[].git
git push --set-upstream origin master
git checkout -b [new branch]
|
远程仓库初始化流程
1
2
3
4
|
su git
mkdir project.git
cd ./project.git
git init --bare
|
提交至romote
1
2
3
4
|
git push
# 在初始提交时可设置追踪
git checkout $local_branch
git push --set-upstream origin $remote_branch
|
忽略已经被 track 的文件或者目录
1
2
3
4
5
6
7
8
|
# 修改.gitignore,添加要忽略的 pattern
vim .gitignore
# 将所有的文件 unstage
git rm --cached -r ./
# 将所有的文件 stage,符合 .gitignore 的文件不被 stage 或者 在 stage Del
git add ./
# 只有被commit 后才不会反复,否则修改只能保留在本次的 stage 区域
git commit
|
撤销上次 megre/rebase
1
2
3
|
# 将分支 reset 到 合并前的commit,commit 一般为HEAD~
# !!!注意:--hard 会覆盖工作目录以及 index
git reset --hard $commit
|
撤销上次提交!!!仅可在未 push 的情况下使用
撤销 git reset –mixed commit1
1
2
3
4
|
# 查看想要恢复到的 $commit2
git reflog
# 将 HEAD,index,workDir 与 commit2 保持一致
git reset --hard $commit2
|
重写 commit message
1
|
git commit -m 'commit message' --amend
|
基于历史提交检出新分支
1
2
3
4
|
# 分离 HEAD 到 $commit
git checkout $commit
# 检出新分支,新分支的 index, workDir 与 commit 同步
git checkout -b $branch_name
|
文件在工作区,暂存区的添加或回退
1
2
3
4
5
6
7
8
|
# 文件从工作区到暂存区
git add ./file
# 文件到暂存区到仓库
git commit
# 文件从工作区到暂存区
git reset HEAD
# 丢弃工作区的修改(用版本库里的版本替换工作区的版本)
git checkout -- file
|
基于远程分支检出本地分支
1
2
3
4
|
# 方法 1:可以直接 clone 远程分支
git clone git_url -b $remote_branch
# 方法 2:基于远程分支检出本地分支
git checkout -b $local_branch $origin/$remote_branch
|
删除远程分支
1
|
git push origin -d $branch
|
以 rebase 的方式 pull
查看当前版本的 commitID
git rev-parse HEAD
查看指定 commit log
1
2
3
4
5
6
7
8
|
# format 可查看 git log --help 搜索PRETTY
# %h short commit hash
# %H full commit hash
# %C(*) * color
# %Creset reset color
# %d ref names, like the --decorate option of git-log(1)
# %s commit msg
git log --pretty='%C(red)%H%Creset - %C(yellow)%d%Creset %s'|grep $commit
|
将仓库打包为 zip
1
|
git archive --format=zip -o latest.zip HEAD
|
clone 时不下载之前的 git 历史
下载之后使用 git commit
只会输出一条记录
1
|
git clone --depth=1 $git_url
|
以压缩包的形式 clone
并非真正的 clone
, 仅下载源文件, 没有 .git 文件夹
1
|
git archive --format=zip -o=test.zip --remote=$git_url
|
submodule
参考 https://devconnected.com/how-to-add-and-update-git-submodules
添加子模块
1
2
3
4
5
6
|
# 方法一(推荐)
git submodule add $(remote_url) $(destination_folder)
# 方法二, 使用 .gitmodules
[submodule "$(destination_folder)"]
path = $(destination_folder)
url = $(remote_url)
|
pull/update 子模块
1
2
3
4
|
# pull Git submodule
git submodule update --init --recursive
# update existing Git submodule
git submodule update --remote --merge
|
移除子模块
1
2
3
4
|
# delete the local submodule configuration;the line referencing the submodule will be deleted from your .git/config file.
git submodule deinit $(submodule)
#delete submodules files
git rm $(submodule)
|
合并commit
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 在合并前可以 checkout 一个分支用来备份 log
# 指定合并区间[$(commit),HEAD]
# commit 可以为 HEAD~x,commit_id
# HEAD~x, x为合并的 commit 数量, 例如 HEAD~6
# 使用 git log 查询 $(commit) 的 id, 例如 3a4226
git rebase -i $(commit)
# 在弹出的 vim 中,修改合并方式
# 例如:除第一个 commit 保留为 pick,其他的 commit 改为 s 或 squash
:wq
# 查看合并结果
git log
# !!!!!! 合并远程分支(会强制覆盖代码,极度危险操作)
git push -f
|
处理冲突
1
2
3
4
5
6
7
8
9
10
|
# 如果要取消本次合并,使用该命令.会重置 stage,workDir
git merge --abort
# 查看冲突的文件,前缀为 UU
git status -s
# 修改冲突文件
vim $file
# 将冲突文件标记为正常,添加文件
git add $file
# 完成全部冲突文件的修改
git commit
|
git diff
1
2
3
4
5
6
7
8
9
10
11
|
git diff #比较 工作目录,暂存区
git diff HEAD #比较 工作区, HEAD
git diff $commit_id #比较 工作区, commit_id
git diff --cached #比较 暂存区,上次提交
git diff --cached $commit_id #比较 暂存区, commit_id
git diff $branch1 $branch2 #比较 分支1,分支2 所有差异文件的详细差异
git diff $branch1 $branch2 $file #比较 分支1,分支2 指定文件的详细差异
git diff $branch1 $branch2 --stat #比较 分支1,分支2 所有差异文件的列表
git diff $commit_id1 $commit_id2 -- name-only #比较 提交1,提交2 所有差异文件的列表
|
Q&A
WARNING: POSSIBLE DNS SPOOFING DETECTED!
.ssh/known_hosts 存在冲突,解决办法
1
|
ssh-keygen -f "/root/.ssh/known_hosts" -R "$host"
|
我们在ssh时,openssh会把访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,openssh会核对公钥。如果公钥不同,openssh会发出警告,避免你受到DNS Hijack之类的攻击。因此我们现在只需要删除knows_hosts文件中所对应的IP节点的公钥,然后再ssh IP地址就可以了。此处使用git操作远程代码库时,使用的是ssh协议,所以出现了这样的问题
祖先提交与父提交
~ 祖先提交 ^ 父提交
~ 表示纵深位置 ^ 表示横向位置
^0,~0 等价 无该参数
~ 等价 ~1
^ 等价 ^1
^^ 等价 ^2
~~ 等价 ~2
例如
$ git log --graph --oneline
* f44239d D
* 7a3fb3d C
|\
| * 07b920c B
|/
* 71bd2cf A
$ git rev-parse HEAD~
7a3fb3d (C)
$ git rev-parse HEAD~^
71bd2cf (A)
$ git rev-parse HEAD~^0
7a3fb3d (C)
$ git rev-parse HEAD~^2
07b920c (B)
$ git rev-parse HEAD~^3
fatal: ambiguous argument 'HEAD~^3': unknown revision or path not in the working tree.
$ git rev-parse HEAD^2
fatal: ambiguous argument 'HEAD^2': unknown revision or path not in the working tree.