总览(2.19.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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 $ git usage: git [--version] [--help ] [-C <path>] [-c <name>=<value>] [--exec -path[=<path>]] [--html-path] [--man-path] [--info-path] [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] <command > [<args>] 这些是各种场合常见的 Git 命令: 开始一个工作区(参见:git help tutorial) clone 克隆一个仓库到一个新目录 init 创建一个空的 Git 仓库或重新初始化一个已存在的仓库 在当前变更上工作(参见:git help everyday) add 添加文件内容至索引 mv 移动或重命名一个文件、目录或符号链接 reset 重置当前 HEAD 到指定状态 rm 从工作区和索引中删除文件 检查历史和状态(参见:git help revisions) bisect 通过二分查找定位引入 bug 的提交 grep 输出和模式匹配的行 log 显示提交日志 show 显示各种类型的对象 status 显示工作区状态 扩展、标记和调校您的历史记录 branch 列出、创建或删除分支 checkout 切换分支或恢复工作区文件 commit 记录变更到仓库 diff 显示提交之间、提交和工作区之间等的差异 merge 合并两个或更多开发历史 rebase 在另一个分支上重新应用提交 tag 创建、列出、删除或校验一个 GPG 签名的标签对象 协同(参见:git help workflows) fetch 从另外一个仓库下载对象和引用 pull 获取并整合另外的仓库或一个本地分支 push 更新远程引用和相关的对象 命令 'git help -a' 和 'git help -g' 显示可用的子命令和一些概念帮助。 查看 'git help <命令>' 或 'git help <概念>' 以获取给定子命令或概念的 帮助。
安装与配置 安装
全局配置 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 30 31 32 33 34 35 36 37 38 39 40 41 $ git config 用法:git config [<选项>] 配置文件位置 --global 使用全局配置文件 --system 使用系统级配置文件 --local 使用仓库级配置文件 -f, --file <文件> 使用指定的配置文件 --blob <数据对象 ID> 从给定的数据对象读取配置 操作 --get 获取值:name [value-regex] --get-all 获得所有的值:key [value-regex] --get-regexp 根据正则表达式获得值:name-regex [value-regex] --get-urlmatch 获得 URL 取值:section[.var] URL --replace-all 替换所有匹配的变量:name value [value_regex] --add 添加一个新的变量:name value --unset 删除一个变量:name [value-regex] --unset -all 删除所有匹配项:name [value-regex] --rename-section 重命名小节:old-name new-name --remove-section 删除一个小节:name -l, --list 列出所有 -e, --edit 打开一个编辑器 --get-color 获得配置的颜色:配置 [默认] --get-colorbool 获得颜色设置:配置 [stdout-is-tty] 类型 -t, --type <> 取值为该类型 --bool 值是 "true" 或 "false" --int 值是十进制数 --bool-or-int 值是 --bool or --int --path 值是一个路径(文件或目录名) --expiry-date 值是一个到期日期 其它 -z, --null 终止值是 NUL 字节 --name-only 只显示变量名 --includes 查询时参照 include 指令递归查找 --show-origin 显示配置的来源(文件、标准输入、数据对象,或命令行) --default <取值> 使用 --get 参数,当缺少设置时使用默认值
1 2 $ git config --global user.name "xxx" $ git config --global user.email "xxx@xxx"
创建版本库 初始化 选择合适的位置并创建一个空目录
1 2 3 4 5 $ mkdir gittest $ cd gittest $ git init 已初始化空的 Git 仓库于 /Users/tonghao/gittest/.git/
添加文件 1 2 $ touch test.txt $ vi test.txt
第一次编辑文本内容为:
I love you
将此文件添加到git仓库有两步:
1 2 3 4 5 6 7 8 $ git add test.txt $ git commit -m "first commit" [master(根提交) 6b774c9] first commit 1 file changed, 1 insertion(+) create mode 100644 test.txt
commit
可以一次提交很多文件,所以可以多次add
不同的文件
版本更新与回退 版本更新 继续修改文件为:
I love you I love you tons
git status
命令可以让我们时刻掌握仓库当前的状态
1 2 3 4 5 6 7 8 9 10 $ git status 位于分支 master 尚未暂存以备提交的变更: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工作区的改动) 修改: test.txt 修改尚未加入提交(使用 "git add" 和/或 "git commit -a" )
上面的命令输出告诉我们,test.txt被修改过了,但还没有准备提交的修改
可以使用git diff
查看修改内容
1 2 3 4 5 6 7 8 9 $ git diff diff --git a/test.txt b/test.txt index 4499f50..ee42064 100644 --- a/test.txt +++ b/test.txt @@ -1 +1,2 @@ I love you +I love you tons
先执行git add
提交到暂存区
1 2 3 4 5 6 7 8 $ git add test.txt $ git status 位于分支 master 要提交的变更: (使用 "git reset HEAD <文件>..." 以取消暂存) 修改: test.txt
执行git commit
把暂存区的所有修改提交到分支
1 2 3 4 5 $ git commit -m "second commit" $ git status 位于分支 master 无文件要提交,干净的工作区
版本回退 再次修改test.txt并提交
I love you I love you tons I love you three thousand
可以使用git log
命令查看历史记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ git log commit c9d8c3067028da10687fa9809365e065c2f4de6a (HEAD -> master) Author: tfcx-th <tonghao_xjtu@qq.com> Date: Tue May 28 15:21:35 2019 +0800 third commit commit 85930502644c8259efba527546620749e7783ee8 Author: tfcx-th <tonghao_xjtu@qq.com> Date: Tue May 28 15:19:09 2019 +0800 second commit commit 6b774c9cd5a5e7889f498300e5aebdcd2d933dff Author: tfcx-th <tonghao_xjtu@qq.com> Date: Tue May 28 14:47:31 2019 +0800 first commit
或者加上--pretty=oneline
1 2 3 4 5 $ git log --pretty=oneline c9d8c3067028da10687fa9809365e065c2f4de6a (HEAD -> master) third commit 85930502644c8259efba527546620749e7783ee8 second commit 6b774c9cd5a5e7889f498300e5aebdcd2d933dff first commit
将test.txt回退版本,可以使用git reset
命令;在git中,HEAD
指向当前版本,上一个版本是HEAD^
,上上个版本是HEAD^^
,上100个版本可以写成HEAD-100
1 2 3 $ git reset --hard HEAD^ HEAD 现在位于 8593050 second commit
查看文件内容
I love you I love you tons
回退以后想要回到原来的版本依然可以使用git reset
,只需要一部分commmit id
即可
1 2 3 git reset --hard c9d8c HEAD 现在位于 c9d8c30 third commit
I love you I love you tons I love you three thousand
可以用git reflog
查看命令历史
1 2 3 4 5 6 7 $ git reflog c9d8c30 (HEAD -> master) HEAD@{0}: reset: moving to c9d8c 8593050 HEAD@{1}: reset: moving to HEAD^ c9d8c30 (HEAD -> master) HEAD@{2}: commit: third commit 8593050 HEAD@{3}: commit: second commit 6b774c9 HEAD@{4}: commit (initial): first commit
撤销修改 假设将test.txt作如下修改
I love you I love you tons I love you three thousand asdasdasdasdasdasdasdasdasd dasdasd
如果在提交之前想撤销这次修改,可以使用git checkout -- <file>
把文件在工作区的修改全部撤销
1 $ git checkout -- test.txt
可以看到,test.txt变回原状态
I love you I love you tons I love you three thousand
如果文件已经添加到暂存区后,又作了修改,撤销修改就回到添加到暂存区后的状态
总之,git checkout -- <file>
就是让文件回到最近一次git commit或git add时的状态
对于已经git add
到暂存区但并没有commit
的文件,可以使用git reset HEAD <file>
把暂存区的修改撤销掉,重新放回工作区,然后再撤销工作区的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ git status 位于分支 master 要提交的变更: (使用 "git reset HEAD <文件>..." 以取消暂存) 修改: test.txt $ git reset HEAD test.txt $ git status 位于分支 master 尚未暂存以备提交的变更: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工作区的改动) 修改: test.txt
删除文件 在git中,删除是一个修改操作
测试一下常见的rm
指令,首先提交一个del_test.txt文件,使用rm
命令
1 2 3 4 5 6 7 8 9 10 11 $ rm del_test.txt $ git status 位于分支 master 尚未暂存以备提交的变更: (使用 "git add/rm <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工作区的改动) 删除: del_test.txt 修改尚未加入提交(使用 "git add" 和/或 "git commit -a" )
此时只删除了工作区的文件,而没有删除版本库中的文件
如果要从版本库中删除该文件,可以使用命令git rm
删掉,并且git commit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ git rm del_test.txt rm 'del_test.txt' $ git status 位于分支 master 要提交的变更: (使用 "git reset HEAD <文件>..." 以取消暂存) 删除: del_test.txt $ git commit -m "delete test" [master 726f4c1] delete test 1 file changed, 1 deletion(-) delete mode 100644 del_test.txt
如果是误删除,可以使用git checkout -- <file>
撤销修改
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以撤销
GitHub远程仓库 本地的git仓库可以关联远程的GitHub。在GitHub上先创建一个repository, 在本地的git仓库输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 $ git remote add origin https://github.com/tfcx-th/gittest.git $ git push -u origin master 枚举对象: 15, 完成. 对象计数中: 100% (15/15), 完成. 使用 4 个线程进行压缩 压缩对象中: 100% (8/8), 完成. 写入对象中: 100% (15/15), 1.13 KiB | 1.13 MiB/s, 完成. 总共 15 (差异 1),复用 0 (差异 0) remote: Resolving deltas: 100% (1/1), done . To https://github.com/tfcx-th/gittest.git * [new branch] master -> master 分支 'master' 设置为跟踪来自 'origin' 的远程分支 'master' 。
把本地库的内容推送到远程,用git push
命令,实际上是把当前分支master推送到远程
由于远程库是空的,第一次推送master分支时要加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
如果远程仓库中本身有文件,git push
后会出现如下情况
1 2 3 4 5 6 7 8 9 $ git push -u origin master To https://github.com/tfcx-th/gittest.git ! [rejected] master -> master (fetch first) error: 推送一些引用到 'https://github.com/tfcx-th/gittest.git' 失败 提示:更新被拒绝,因为远程仓库包含您本地尚不存在的提交。这通常是因为另外 提示:一个仓库已向该引用进行了推送。再次推送前,您可能需要先整合远程变更 提示:(如 'git pull ...' )。 提示:详见 'git push --help' 中的 'Note about fast-forwards' 小节。
此时需要先git pull
,但会有如下问题
1 2 3 4 5 6 7 8 9 10 11 12 $ git pull origin master warning: 没有共同的提交 remote: Enumerating objects: 3, done . Merge branch 'master' of https://github.com/tfcx-th/gittest remote: Counting objects: 100% (3/3), done . remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 展开对象中: 100% (3/3), 完成. 来自 https://github.com/tfcx-th/gittest * branch master -> FETCH_HEAD * [新分支] master -> origin/master fatal: 拒绝合并无关的历史
可以这样解决这个问题
1 2 3 4 5 6 7 8 9 10 11 $ git pull origin master --allow-unrelated-histories Merge branch 'master' of https://github.com/tfcx-th/gittest 来自 https://github.com/tfcx-th/gittest * branch master -> FETCH_HEAD Merge made by the 'recursive' strategy. README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md
之后就可以顺利git push
了