GIT使用手册

一、基本命令

1.1 版本回退

1
2
3
4
5
git reset --hard # 回退到当前版本(放弃所有修改)
git checkout {file_name} # 放弃某个文件的修改
git reset {UUID} # 回退到某一版本但保存自该版本起的修改
git reset --hard {UUID} # 回退到某一版本并且放弃所有的修改
git reset --hard origin/master # 回退到和远程版本一样, origin代表你远程仓库的名字,master代表分支名

1.2 git submodule使用

这其实是 git 的子模块功能,作用是为了在项目中引入另一个项目的部分或全部内容,但是这两个项目是分开开发或管理的,这样直接使用 git submodule 就可以不必要将另一个项目复制一份直接引用即可。

常用 git submodule命令

1
2
3
4
5
6
7
8
9
10
11
12
13
git submodule add repourl # 添加 git 子模块
git submodule init # 初次clone带有子模块的仓库如果想查看子模块的内容
git submodule update # 或者 git submodule update --init --recursive
vi .gitmodules # 更新子模块地址
git submodule sync # 然后提交更改即可
git rm --cached {submodule_path} # submodule_path即子模块在仓库下的路径(这之前需要删除删除 .gitsubmodule中对应submodule的条目 和 删除 .Git/config 中对应submodule的条目)
git commit -m 'xxx'
git push

具体的关于 git submodule 的说明以及使用,请点击这里

1.3 分支合并

分支合并分为两种情况,一种是本地分支合并,一种是远程分支合并到本地分支

1
2
git merge 分支名称 # 本地分支合并
git pull origin master # 远程分支合并到本地分支

1.4 代码提交

1.4.1 如何从众多提交中保留只需要的提交

如果说在众多提交中,已某个提交为基准,只保留上游众多提交中的某个或者某几个,可以使用 cherry-pick命令,具体是:

git cherry-pick

如果没有冲突,则回显示如下:

1
2
3
Finished one cherry-pick.
# On branch dev
# Your branch is ahead of 'origin/dev' by 3 commits.

如果存在冲突,则需要解决冲突然后继续,关于如何冲突,请查看如何处理代码冲突小节

1.4.2 修改最后一次提交

更多参考:http://git.mydoc.io/?t=83152

1.4.5 改写历史,去除大文件

1
2
3
git filter-branch --tree-filter 'rm -f path/to/large/files' --tag-name-filter cat -- --all
git push origin --tags --force
git push origin --all --force

并告知所有组员,push 代码前需要 pull rebase,而不是 merge,否则会从该组员的本地仓库再次引入到远程库中

1.4.6 恢复已经被删除文件

git checkout commit_id -- path_to_file
可以试一下使用git ls-files -d | xargs -i git checkout {} 不过新的版本开始不支持了!

1.4.7 批量永久删除git中文件

1
2
3
4
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch projects/Moon.mp3' --prune-empty --tag-name-filter cat -- --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch sound/Music_*.mp3' --prune-empty --tag-name-filter cat -- --all
git push origin master --force --all # 强制覆盖推送

二、配置

http(s)方式自动记住密码

1
2
3
git config --global credential.helper cache # 记住密码十五分钟
git config credential.helper 'cache --timeout=3600' # 这里记住的是一个小时,如需其他时间,请修改3600为你想修改的时间,单位是秒
git config --global credential.helper store # 设置长期记住密码 或者,比如http://yourname:password@git.oschina.net/name/project.git //注意,码云平台同时支持个性地址与邮箱,当使用邮箱时,请对@符号使用%40替换

如果你原本使用的 ssh 地址想更换成 http(s) 地址,可以执行以下命令:

1
2
git remote rm origin # 删除原本的ssh仓库地址 origin 代表你原本ssh地址的仓库的别名
git remote add origin http://git.oschina.net/username/project.git # 新增http地址的仓库

CRLF换行输入问题

git 出现warning crlf will be replaced by…
里面的文本文件所使用的换行符,在不同的系统平台上是不一样的。UNIX/Linux 使用的是 0x0A(LF),早期的 Mac OS 使用的是 0x0D(CR),后来的 OS X 在更换内核后与 UNIX 保持一致了。但 DOS/Windows 一直使用 0x0D0A(CRLF) 作为换行符。
跨平台协作开发是常有的,不统一的换行符确实对跨平台的文件交换带来了麻烦。最大的问题是,在不同平台上,换行符发生改变时,Git 会认为整个文件被修改,这就造成我们没法 diff,不能正确反映本次的修改。

还好 Git 在设计时就考虑了这一点,其提供2个选项进行操作

autocrlf配置

git config –global core.autocrlf {true|false|input}

参数说明:

  • true: 提交时转换为LF,检出时转换为CRLF
  • input: 提交时转换为LF,检出时不转换
  • false: 提交检出均不转换

在 Windows 上,系统默认配置一般为 true。如果文件编码是 UTF8 并且包含中文字符,那最好还是把 autocrlf 设置为 false。否则,就会遇到我所遇到的问题,Git 尝试将 CRLF 转化为 LF 时失败,导致无法 add 。

如果把 autocrlf 设置为 false 时,那另一个配置项 safecrlf 最好设置为 ture。该选项用于检查文件是否包含混合换行符,其有三个可选项.

safecrlf配置

git config –global core.safecrlf {true|false|warn }

  • true: 拒绝提交包含混合换行符的文件
  • false: 允许提交包含混合换行符的文件
  • warn: 提交包含混合换行符的文件时给出警告

综合方案

mac下,如果有mac和windows开发用户,可以这样设置:

1
2
git config --global core.autocrlf false
git config --global core.safecrlf warn 或false

虽然代码能被提交,但是项目中的文件可能会包含两种格式的换行符。而且会有如上提到的问题,文件被视为整个被修改,无法 diff,之所以使用版本控制工具,最重要的原因之一就是其 diff 功能。

最好默认选择LF,或者强制转成LF,没办法,用windows的码农且不会配置LF的太多太多。。。

三、迁移git

3.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
## Git global setup
git config --global user.name "xxx"
git config --global user.email "xx@xx.com"
## Create a new repository
git clone git@gitlab.com:xxx/xxx.git
cd your_dir
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
## Existing folder
cd existing_folder
git init
git remote add origin git@gitlab.com:xxx/xxx.git
git add .
git commit -m "Initial commit"
git push -u origin master
## Existing Git repository
cd existing_repo
git remote rename origin old-origin
git remote add origin git@gitlab.com:xxx/xxx.git
git push -u origin --all
git push -u origin --tags