Git笔记
起步
什么是Git
分布式的版本控制系统
初次运行Git前的配置
设置用户名
$ git config --global user.name "John Doe"
设置邮件地址$ git config --global user.email johndoe@example.com
查看配置信息$ git config --list
检查某一项配置$ git config <key>
获取git命令的使用手册$ git help <verb>
Git基础
获取Git仓库
- 初始化仓库
$ git init
- 克隆现有的仓库
-
git clone <URL>
获取默认分支代码$ git clone https://github.com/libgit2/libgit2
-
git clone <URL> <新名字>
拉取仓库时自定义本地仓库文件名$ git clone https://github.com/libgit2/libgit2 mylibgit
-
git clone -b <分支名> <代码地址>
直接拉取特定分之的代码$ git clone -b dev http://192.168.102.9/jas-paas/cloudlink-front-framework.git
-
git clone -b <标签名> <代码地址>
直接拉取特定标签(tag)的代码$ git clone -b V2.2 http://192.168.102.9/jas-paas/cloudlink-front-framework.git
.gitignore 忽略文件,不纳入GIT版本控制
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
# 忽略所有后缀为 .a 的文件
*.a
# 但是要跟踪lib.a,即使你上面忽略了 .a文件
!lib.a
# 仅忽略当前目录的TODO文件夹, 不是subdir/TODO
/TODO
# 忽略build /目录中的所有文件
build/
# 忽略doc / notes.txt,而不是doc / server / arch.txt
doc/*.txt
# 忽略doc 目录中的所有.pdf文件
doc/**/*.pdf
文件状态介绍
- Changes to be committed 已暂存
- Changes not staged for commit 已修改
- Untracked files 未跟踪
检查当前文件状态
$ git status
$ git status -s // 或者 git status -short , 紧凑格式输出
跟踪新文件(并把已跟踪文件放到暂存区)
$ git add src/test.txt // 指定单个文件添加
$ git add src/* // 指定src目录下所有文件都添加
$ git add . // 全部添加
git checkout -- <file>
撤销对文件的修改(该文件任何修改都会消失!)
$ git checkout -- CONTRIBUTING.md
git reset HEAD -- <file>
取消暂存的文件(将文件从暂存区回退到工作区)
$ git reset HEAD CONTRIBUTING.md
git diff
查看尚未暂存的文件修改记录 (Changes not staged for commit 下面的文件)
$ git diff // 查看所有已暂存文件的修改记录 $ git diff t.txt // 只查看1.txt文件 已暂存的修改记录
git diff --staged
查看已暂存文件修改记录$ git diff --staged // 查看所有已暂存文件的修改记录 $ git diff --staged t.txt // 只查看1.txt文件 已暂存的修改记录
其他用法
$ git diff --stat // 查看简单的diff结果,只查看修改的文件名、修改了多少内容 $ git diff HEAD // 查看所有修改记录(已暂存、已修改)显示(Working tree)和HEAD的差别 $ git diff topic master // 直接将两个分支上最新的提交做diff $ git diff HEAD^ HEAD // 比较上次提交commit和上上次提交 $ git diff SHA1 SHA2 // 比较两个历史版本之间的差异
git commit
提交更新(暂存区提交到仓库区)
$ git commit // 会启动文本编辑器以便输入本次提交的说明
$ git commit -m "Story 182: Fix benchmarks for speed" // 将提交信息与命令放在同一行
$ git commit -a -m 'added new benchmarks' // 跳过使用暂存区域
$ git commit --amend // 如果漏掉了文件没有添加,或者提交信息写错了,可以尝试重新添加
git log
查看提交历史,方便版本回滚
$ git log 1.txt // 查看 1.txt文件的历史修改记录
$ git log -n // 只查看前n次修改记录,例如查看前2次的记录:git log -2
$ git log -p // 按补丁格式显示每个更新之间的差异
$ git log --stat // 显示每次更新统计信息(修改的文件名,每个文件添加的多少、删除了多少数字)
$ git log --shortstat // 只显示 --stat 中最后的行数修改添加移除统计。
$ git log --name-status // 显示新增、修改、删除的文件清单。
$ git log --name-only // 只显示修改的文件名,没有其他信息
$ git log --abbrev-commit // 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
$ git log --relative-date // 使用较短的相对时间显示(比如,“2 weeks ago”)。
$ git log --graph // 显示 分支合并历史。
$ git log --pretty=oneline // 用一行显示信息
git reset (--mixed) HEAD~1
撤销commit和add,工作区内容不变
回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也
不受影响)
git reset --soft HEAD~1
仅撤销commit,暂存区、工作区内容不变
回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响)
git reset --hard HEAD~1
(危险操作,数据会丢失)
想恢复到某个版本库的代码(暂存区,工作区均变化)
回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换
远程仓库的使用
查看远程仓库
$ git remote // 指定的远程服务器的简写,origin - 这是 Git 给你克隆的仓库服务器的默认名字
origin
$ git remote -v // 读写远程仓库使用的 Git 保存的简写与其对应的 URL
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
git remote add <shortname> <url>
添加远程仓库
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
git fetch [remote-name]
从远程仓库中抓取与拉取
git pull <仓库名> <分支名>
有多个远程仓库,拉取指定仓库
$ git pull github master // 比如远程仓库有origin、github,默认origin,如果拉取github仓库的代码
远程仓库的重命名与移除
$ git remote rename pb paul
$ git remote
origin
paul
$ git remote rm paul
$ git remote
origin
打标签
查看标签
git tag
列出所有标签$ git tag v0.1 v1.3 v1.4
查看符合条件的标签
$ git tag -l 'v1.*' // 只查看1.0以上tag
查看一个标签的详细信息
$ git tag show V1.4
创建标签
git tag -a
创建附注标签(annotated)附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。
$ git tag -a v1.4 -m 'my version 1.4' // -m 选项指定了一条将会存储在标签中的信息。 如果没有 为附注标签指定一条信息,Git 会运行编辑器要求你输入信息。
创建轻量标签(lightweight)
如果你只是想用一个临时的标签,或者因为某些原因不想要保存那些信息,则可以选择使用轻量标签。轻量标签本质上是将提交校验和存储到一个文件中 – 没有保存任何其他信息。
创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字$ git tag v1.4-lw $ git tag v1.4 v1.4-lw
后期打标签
如果你在项目版本发布的时候忙忘记打标签,你可以在之后补上标签。
要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和)git tag -a v1.2 9fceb02
git push origin [tagname]
共享标签(把创建的标签推送到服务器上)
默认情况下,git push
命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。
$ git push origin v1.5
$ git push origin --tags // 把所有不在远程仓库服务器上的标签全部传送到服务器
检出标签: 代码变成标签的样子
在 Git 中你并不能真的检出一个标签,因为它们并不能像分支一样来回移动。
如果你想要工作目录与仓库中特定的标签版本完全一样,
可以使用git checkout -b [branchname] [tagname]
在特定的标签上创建一个新分支
$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'
删除标签
$ git tag -d v1.0 // 删除本地标签
$ git push origin :refs/tags/v0.1 // 删除服务器标签
如果服务器的标签删除后,本地的也需要自己删除。
Git分支
分支介绍
Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支名字是 master。
在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 它会在每次的提交操作中自动向前移动。
分支作用:
- 开发多个项目任务,比如说我有两个任务都比较紧急,任务1需要两天完成,任务2需要一天完成,而任务1是之前就已经开始进行的,任务二是中间加的新任务,所以需要第一天就完成任务2.
- master分支始终要保证可发布的状态,用dev分支和bug分支进行开发和错误调试,这样能够保证主干代码的干净、可发布。
- 自己开发测试或者修复BUG等等,可以避免代码的丢失。
本地分支的创建、切换、删除
git branch
创建分支
$ git branch testing // 创建一个 testing 分支
git checkout
切换分支
$ git checkout testing // 切换到 testing 分支
git checkout -b
创建并切换
$ git checkout -b testing
Switched to a new branch "testing"
git checkout -b <分支名> <远程仓库名>/<分支名>
创建分支并拉取远程分支代码(已经拉取了代码,还需要拉取其他分支的代码)
$ git checkout -b develop origin/develop // 提取远程新分支到本地
git branch -d
删除分支
$ git branch -d testing
Deleted branch testing (was 4baf2a3).
远程分支的新建与删除
git branch -a
查看远程仓库分支
git push origin
新建远程仓库的分支
$ git br -a
testing
* master
remotes/origin/master
$ git push origin testing // 将本地 testing 分支作为远程 testing 分支
Total 0 (delta 0), reused 0 (delta 0)
To http://192.168.132.00/user/test.git
* [new branch] testing -> testing
git push origin --delete
删除远程仓库的无用分支
git push origin --delete testing
To http://192.168.132.00/user/test.git
- [deleted] testing
git push
将本地的更新推送到远程仓库
$ git push origin master // 把更新上传到 origin 服务器的 master 分支上
$ git push // 上传本地所有分支代码到远程对应的分支上
git pull origin <分支>
取回远程仓库的变化,并自动与本地分支合并
git fetch origin <分支>
从远程获取最新变化到本地,但不会自动merge
分支合并 git merge
例如,现在有2个分支(master, ningning),master分支的代码要合并到ningning,2个分支代码都已经commit过了。如果没有commit,需要先commit,否则不能合并代码。
git merge <分支名>
合并命令
// 切换到需要添加新功能的分支上
$ git checkout ningning
// 把 master分支上的代码合并到ningning分支上
$ git merge master
直接合并成功的提示
$ git merge master
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
// 或者下面的输出信息
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Git 将合并的结果做了一个新的快照并且自动创建一个新的提交指向它。
遇到冲突时的分支合并
错误信息类似于
Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.
Auto-merging是指已经自动合并的文件
CONFLICT (content)是指有冲突的文件,需要解决冲突的文件。
打开有冲突的文件,冲突部分代码类似于下面:
<<<<<<< HEAD:ningning <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> master
<<<<< ======= 中的是 ningning分支的代码。
======= >>>>>> 中的是 master分支的代码。
经过对比后删除冲突部分的代码, 并把 <<< ==== >>>> 所在行全部删除。
保存后,使用git add
添加修改的文件。
使用git commit
命令来完成合并提交:
git checkout --ours/--theirs
放弃其中一个分支的冲突代码
如果想放弃一个分支文件的冲突代码,只保留一个分支的代码,可使用如下命令。
假如:冲突文件名为 1.txt,要放弃master
分支的修改,可使用如下命令:
$ git checkout --ours 1.txt
放弃ningning
分支冲突代码,可使用如下命令:
$ git checkout --theirs 1.txt
git reset --hard HEAD
取消合并
如果冲突代码太多了,解决冲突代码过程中产生了混乱,想要重新合并,可使用下面命令取消这次合并:
git reset --hard HEAD HEAD is now at 9e791f3 提交信息
如果合并的代码产生了错误,或者合并有问题,但是已经commit了,但是还没有把合并提交到远程仓库,则可以使用如下命令取消这次合并:
$ git reset --hard HEAD^