本地仓库git命令练习 在一个合适目录下,创建一个空白文件夹 1 2 3 4 5 $ cd /Users/czm/work/gitTest $ mkdir learngit $ cd learngit $ pwd /Users/czm/work/gitTest/learngit
通过 git init
命令把这个目录变成Git可以管理的仓库: 1 2 3 4 $ pwd /Users/czm/work/gitTest/learngit $ git init Initialized empty Git repository in /Users/czm/work/gitTest/learngit/.git/
此时一个空的git仓库创建好了,当前目录下多了 .git 目录,.git目录用来跟踪管理版本库,不可修改里面的文件。
git add
保存到暂存区新建一个 1.text 文件,然后拖动到 learngit 目录下,执行以下命令保存到暂存区。
1 2 3 4 $ git add 1.text # 或者, 表示把工作区中所有修改过的文件保存到暂存区 $ git add .
git add命令的作用: 1、跟踪新文件 2、遇到冲突时的分支合并 3、git add -i
:交互式暂存
保存到本地库 git commit
命令将所有通过 git add
暂存的文件内容在数据库中创建一个持久的快照,然后将当前分支上的分支指针移到其之上。
1 2 3 4 $ git commit -m 'initial project version' # 或者, 跳过 git add 步骤,把所有已经跟踪过的文件暂存起来一并提交 $ git commit -a -m 'added new benchmarks'
查看当前文件状态 显示当前所在分支,以及工作目录下文件的状态。
1 2 $ git status $ git status --short or git status -s
分别看看几种状态下文件的状态,执行如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 1、新建1.text,保存到版本库后,修改文件并保存到暂存区 $ git add 1.text $ git commit -m "添加1.text" # 2、新建2.text,保存到版本库后,再修改2.text内容 $ git add 2.text $ git commit -m "添加2.text" 修改2.text # 3、新建3.text,保存到版本库后,修改3.text内容保存到暂存区,再次修改3.text $ git add 3.text $ git commit -o 3.text -m "只保存3.text" 修改3.text $ git add 3.text 修改3.text # 4、新建4.text,跟踪4.text文件 $ git add 4.text # 5、新建5.text
git status
命令执行后的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 On branch master Changes to be committed: # 要提交的更改,在暂存区 (use "git restore --staged <file>..." to unstage) modified: 1.text # 修改了已跟踪的文件 modified: 3.text # 修改了亿跟踪的文件 new file: 4.text # 新跟踪文件,已暂存文件,该文件不在 Git 之前的快照(提交)中。 Changes not staged for commit: # 未准备提交的更改: 修改了已跟踪的文件,未保存到暂存区 (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: 2.text modified: 3.text Untracked files: # 未跟踪的文件:在工作区新添加的文件,但未保存到暂存区 (use "git add <file>..." to include in what will be committed) 5.text
git status -s
命令执行后的结果:
1 2 3 4 5 M 1.text M 2.text MM 3.text A 4.text ?? 5.text
查看修改文件内容的差异 1、git diff
未暂存文件的修改 它比较的是工作区中的文件 和 暂存区域快照之间的差异。
2、git diff --staged
查看已暂存文件的修改,或者git diff --cached
它比较的是 已暂存文件 与 最后一次提交的文件差异。
我们一般使用图形化的工具或外部 diff 工具来比较差异。
删除文件 1、如果需要删除的已跟踪文件在上次提交后都未被更改过时,使用以下命令:
该命令会把文件从工作区目录中删除,并且从已跟踪文件清单(暂存区)中移除。然后我们需要提交到版本库:
1 $ git commit -m "删除了4.text"
2、如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 -f
3、如果我们只需要删除暂存区中的某个文件,保留工作区的文件。(也就是删除提交忽略文件的情况)
1 2 3 4 5 6 $ git rm --cached 3.text $ git commit -m "删除3.text" # 添加.gitignore文件 $ git add .gitignore $ git commit -m "添加忽略文件" $ git status
修改文件名称 1 2 3 4 5 6 $ git mv file_from file_to 相当于执行了下面操作: mv README.md README git rm README.md git add README
查看提交历史 1 2 3 4 5 $ git log $ git log -p $ git log -p -2 $ git log --stat -2 $ git log --pretty=oneline
撤消操作 1、重新提交 如果刚进行了commit,或者漏掉了需要提交的内容,或者你是需要修改上次的提交信息,可以使用如下命令,它会把暂存区的文件一起提交,在历史记录中替代上次的提交:
git commit --amend -m "重新提交"
2、取消暂存的文件 只是取消了提交到暂存区,本地文件的修改Git仍然保存着记录
3、取消对未暂存文件的修改 工作区文件被修改,未暂存,如下命令可取消文件的本地修改:
未跟踪的新文件被暂存后,进行撤销:
1 git restore --staged 4.text
4、取消对已commit文件的修改 使用 git checkout 后,Git 会用最近提交的版本覆盖掉本地的任何操作。
该命令很危险,会撤销掉本地的一切修改,
1 $ git checkout -- 2.text
远程仓库的基本使用 远程仓库是指托管在因特网或其他网络中的你的项目的版本库。远程仓库未必表示仓库在网络或互联网上的其它位置,它也可以在你的本地的主机上。每个本地仓库可以有好几个远程仓库,用于与他人协作涉及管理远程仓库。
管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。
clone 一个远程仓库
执行克隆后,Git会自动将clone的仓库添加为远程仓库,并自动以 “origin” 命名该远程仓库,并创建一个 master 分支的指针指向该远程仓库,并且在本地生成一个名为 origin/master 的远程分支。并且拉取远程仓库的所有数据到本地,Git 也会给你一个与 origin 的 master 分支在指向同一个地方的本地 master 分支,作为工作的基础分支。
git clone [remote-repository] [local-repository]
clone命令会自动地创建一个跟踪 origin/master 的 master 分支。
1 2 3 4 5 6 7 8 9 10 11 12 # 克隆远程仓库 $ git clone /Users/czm/work/gitTest/learngit /Users/czm/work/gitTest/newLearngit $ cd newLearngit/ # 查看远程仓库服务器的简写,origin是 Git 给你克隆的仓库服务器的默认名字 $ git remote origin # 显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL $ git remote -v origin /Users/czm/work/gitTest/learngit (fetch) origin /Users/czm/work/gitTest/learngit (push)
添加远程仓库 给原有的本地仓库添加一个新的远程 Git 仓库,shortname 用于在命令行中代替整个 URLgit remote add <shortname> <url>
1 2 3 4 5 $ cd learngit/ $ git remote add gitTest git@github.com:czmCWH/gitTest.git $ git remote -v gitTest git@github.com:czmCWH/gitTest.git (fetch) gitTest git@github.com:czmCWH/gitTest.git (push)
从远程仓库中抓取(fetch) fetch 命令,拉取远程仓库中有而本地没有的数据,它会抓取远程仓库中所有新的分支引用(指针)。
fetch 操作会抓取克隆(或上一次抓取)后新推送的所有工作,只是将数据下载到你的本地仓库,我们需要手动将数据合并到我们本地的分支上。
从远程仓库中拉取(pull) 如果你的当前分支设置了跟踪远程分支,可以在跟踪分支上输入 git pull
命令来自动抓取后合并该远程分支到当前分支。
大多数情况下 git pull
的含义是一个 git fetch 紧接着一个 git merge 命令。 由于 git pull
的魔法经常令人困惑所以通常单独显式地使用 fetch
与 merge
命令会更好一些。
推送到远程仓库 将本地的分支推送到服务器:git push <remote> <branch>
1 2 3 4 5 6 7 8 $ cd learngit/ $ git status On branch master nothing to commit, working tree clean $ git remote -v gitTest git@github.com:czmCWH/gitTest.git (fetch) gitTest git@github.com:czmCWH/gitTest.git (push) $ git push gitTest master
查看某个远程仓库更多信息 git remote show <remote>
该命令会列出远程仓库的 URL 与跟踪分支的一些信息: 1、git push 会自动地推送到哪一个远程分支 2、哪些远程分支不在你的本地 3、哪些远程分支已经从服务器上移除 4、git pull 时哪些本地分支可以与它跟踪的远程分支自动合并
1 2 3 4 5 6 7 8 9 10 11 $ git remote gitTest $ git remote show gitTest * remote gitTest Fetch URL: git@github.com:czmCWH/gitTest.git Push URL: git@github.com:czmCWH/gitTest.git HEAD branch: master Remote branch: master tracked Local ref configured for 'git push': master pushes to master (up to date)
远程仓库的重命名与移除 git remote rename <old> <new>
来修改一个远程仓库的简写名
1 2 3 4 5 6 7 $ git remote -v gitTest git@github.com:czmCWH/gitTest.git (fetch) gitTest git@github.com:czmCWH/gitTest.git (push) $ git remote rename gitTest learnGit $ git remote -v learnGit git@github.com:czmCWH/gitTest.git (fetch) learnGit git@github.com:czmCWH/gitTest.git (push)
git remote remove
或 git remote rm
移除一个远程仓库
1 2 3 4 5 6 7 8 9 10 $ git remote rm learnGit ``` # Git 可以给仓库历史中的某一个提交打上标签,以示重要。 1、轻量标签(lightweight) 它只是某个特定提交的引用,很像一个不会改变的分支。轻量标签本质上是将提交校验和存储到一个文件中——没有保存任何其他信息。创建轻量标签,不需要选项,只需要提供标签名字。 ```shell $ git tag v1.0.1
2、附注标签(annotated) 它是存储在 Git 数据库中的一个完整对象。它是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息。
1 $ git tag -a v1.0.0 -m "initial project version"
1 2 3 4 5 6 7 8 9 10 11 12 13 // 列出已有的标签 $ git tag v1.0.0 v1.0.1 $ git tag -l v1.0.0 v1.0.1 # 按照通配符列出标签 $ git tag -l "v1.*.*" v1.0.0 v1.0.1 # 查看标签信息和与之对应的提交信息 $ git tag show v1.0.0
后期打标签 要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和)
1 2 3 4 5 6 7 $ git log --pretty=oneline $ git tag -a v1.1.1 dc9c895262d2b1e5c6f304a6a2331fb9c30cf292 -m "后期打标签1" $ git tag show v1.0.0 v1.0.1 v1.1.1
把标签同步到git服务器上 默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。git push origin-remote <tagname>
1 2 3 4 5 $ git remote learnGit $ git push learnGit v1.0.0 # 把所有不在远程仓库服务器上的标签全部传送 $ git push learnGit --tags
删除标签 删除掉你本地仓库上的标签:
将冒号前面的空值推送到远程标签名,从而高效地删除它:
1 2 3 $ git remote learnGit $ git push learnGit :refs/tags/v1.1.1
更直观的方式删除远程标签:
1 2 3 $ git remote learnGit $ git push learnGit --delete v1.0.1
检出标签
检出标签会使你的仓库处于“分离头指针(detached HEAD)”的状态,这个状态有些不好的副作用。
一般操作是根据标签创建一个新分支:
1 2 3 4 $ git checkout -b version1.0.0 v1.0.0 $ git branch -v master f6d040f 添加README.md * version1.0.0 f6d040f 添加README.md
Git分支 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。Git 鼓励在工作流程中频繁地使用分支与合并。
1 2 3 4 5 6 7 8 # 查看本地仓库中所有的分支 $ git branch -a # 查看所有本地远程分支引用 $ git branch -r # 查看设置的所有跟踪分支 $ git branch -vv
新建本地分支 新建一个本地分支并同时切换到那个分支上
方式一:
1 2 3 4 5 6 $ git checkout -b develop # 查看当前所有分支 $ git branch -v * develop f6d040f 添加README.md master f6d040f 添加README.md version1.0.0 f6d040f 添加README.md
方式二:
1 2 3 4 # 新建分支 $ git branch develop # 切换分支 $ git checkout develop
合并分支 develop 分支上修改后,合并到 master 分支上
1 2 3 4 $ git checkout develop $ git commit -a -m "修改了5.text" $ git checkout master $ git merge develop
删除分支 1 2 3 4 5 6 7 8 9 10 11 12 $ git checkout master Switched to branch 'master' $ git branch develop * master version1.0.0 # 删除分支version1.0.0 $ git branch -d version1.0.0 Deleted branch version1.0.0 (was f6d040f). $ git branch develop * master
遇到冲突时的分支合并 合并冲突的产生:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 新建分支dayTest,修改5.text提交后,合并到master分支 $ git checkout -b dayTest $ git branch * dayTest develop master $ git commit -a -m "修改了5.text" $ git checkout master $ git merge dayTest Updating b735231..989d101 Fast-forward 5.text | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) # 切换到develop分支,修改5.text并提交 $ git checkout develop $ git commit -a -m "修改了5.text" # 把develop分支合并到master分支,合并失败,发生了冲突 $ git checkout master $ git merge develop Auto-merging 5.text CONFLICT (content): Merge conflict in 5.text Automatic merge failed; fix conflicts and then commit the result.
产生合并冲突后,Git 只做了合并,但是没有自动地创建一个新的合并提交。
1 2 3 4 5 6 7 8 9 10 11 $ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: 5.text no changes added to commit (use "git add" and/or "git commit -a")
我们需要打开冲突文件,根据 Git 在冲突文件中加入标准的冲突解决标记,进行手动修改内容,然后去掉 冲突标记。
1 2 3 4 5 6 7 8 9 10 白日依山尽,黄河入海流 欲穷千里目,更上一层楼 <<<<<<< HEAD # 运行 git merge 命令时所在的分支 大漠孤烟直 ======= 长河落日圆 > >>>>>> develop
解决冲突后,通过 git add 命令来将其标记为冲突已解决,最后 git commit 来完成合并提交。
1 2 3 4 5 $ git add 5.text $ git commit -m "合并develop到master" $ git status On branch master nothing to commit, working tree clean
分支管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 查看当前所有分支的一个列表 $ git branch dayTest develop * master # * 表示当前 HEAD 指针所指向的分支 # 查看每一个分支的最后一次提交 $ git branch -v # 尚未合并到当前分支的分支 $ git branch --no-merged # 已合并到当前分支的分支 $ git branch --merged
1 2 3 4 $ git branch -d test error: The branch 'test' is not fully merged. If you are sure you want to delete it, run 'git branch -D test'. $ git branch -D test
分支开发工作流 分支策略(branching scheme):
master分支:保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。
develop 或者 next 的平行分支:用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master 分支了。
主题分支(短期分支):用于功能性开发,最终合并到develop分支上。(如:feature/:新功能分支;release/ :发布分支,基于develop最新版本创建的分支,用来测试,测试的bug会在这个分支上进行修改;hotfix/*:线上版本修复bug的分支,基于master创建)
推送本地分支到远程 git push <remote> <branch>
本地的分支并不会自动与远程仓库同步——你必须显式地推送想要分享的分支。
1 2 3 4 5 6 7 8 9 $ git branch dayTest * develop master $ git remote -v learnGit git@github.com:czmCWH/gitTest.git (fetch) learnGit git@github.com:czmCWH/gitTest.git (push) $ git push learnGit develop $ git ls-remote learnGit
远程分支 远程引用:是对远程仓库的引用(指针),包括分支、标签等等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ git remote learnGit # 查看远程引用的完整列表 $ git ls-remote learnGit # 获得远程分支的更多信息 $ git remote show learnGit * remote learnGit Fetch URL: git@github.com:czmCWH/gitTest.git Push URL: git@github.com:czmCWH/gitTest.git HEAD branch: master Remote branches: develop tracked master tracked Local refs configured for 'git push': develop pushes to develop (up to date) master pushes to master (fast-forwardable)
远程跟踪分支:它是远程分支状态的引用,存储在本地。一旦你进行了网络通信, Git 就会为你移动它们以精确反映远程仓库的状态。它们以 <remote>/<branch> 的形式命名。
git fetch <remote>
命令的作用: 1、 从远程仓库抓取本地没有的数据,并且更新本地数据库,更新你的远程跟踪分支(即:移动 origin/master 指针到更新之后的位置); 2、对添加另一个远程仓库设置一个新的远程跟踪分支;
跟踪分支: 跟踪分支(上游分支):从一个远程跟踪分支检出一个本地分支会自动创建所谓的“跟踪分支”,跟踪分支是与远程分支有直接关系的本地分支。
创建跟踪分支的方式:
1 2 3 4 5 6 7 8 9 # 方式一:git clone :clone 命令会自动地创建一个跟踪 origin/master 的 master 分支 # 方式二:从一个远程跟踪分支检出 $ git checkout -b <branch> <remote>/<branch> 或者 将本地分支与远程分支设置为相同的名字,上面可以定义不同的名字 $ git checkout --track <remote>/<branch> # 方式三:设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支 $ git branch -u(或者 --set -upstream-to) <remote>/<branch>
git branch -vv
:查看设置的所有跟踪分支,会列出每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有。这些数据来自每个服务器上最后一次的抓取,即本地缓存的服务器数据。因此,需要在运行此命令前抓取所有的远程仓库,如下:
1 2 $ git fetch --all $ git branch -vv
删除远程分支 基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。
1 $ git push <remote> --delete <remote>