git的使用(二)

本地仓库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 rm 4.text

该命令会把文件从工作区目录中删除,并且从已跟踪文件清单(暂存区)中移除。然后我们需要提交到版本库:

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 # 此时3.text不在受git跟踪管理了

修改文件名称

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 # 或 --patch ,它会显示每次提交所引入的差异
$ git log -p -2 # 只显示最近的两次提交
$ git log --stat -2 # 查看每次提交的简略统计信息
$ git log --pretty=oneline # 简略浏览大量的提交

撤消操作

1、重新提交
如果刚进行了commit,或者漏掉了需要提交的内容,或者你是需要修改上次的提交信息,可以使用如下命令,它会把暂存区的文件一起提交,在历史记录中替代上次的提交:

git commit --amend -m "重新提交"

2、取消暂存的文件
只是取消了提交到暂存区,本地文件的修改Git仍然保存着记录

1
$ git reset HEAD 2.text

3、取消对未暂存文件的修改
工作区文件被修改,未暂存,如下命令可取消文件的本地修改:

1
git restore 2.text

未跟踪的新文件被暂存后,进行撤销:

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 用于在命令行中代替整个 URL
git 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 操作会抓取克隆(或上一次抓取)后新推送的所有工作,只是将数据下载到你的本地仓库,我们需要手动将数据合并到我们本地的分支上。

1
git fetch gitTest

从远程仓库中拉取(pull)

如果你的当前分支设置了跟踪远程分支,可以在跟踪分支上输入 git pull 命令来自动抓取后合并该远程分支到当前分支。

大多数情况下 git pull 的含义是一个 git fetch 紧接着一个 git merge 命令。 由于 git pull 的魔法经常令人困惑所以通常单独显式地使用 fetchmerge 命令会更好一些。

推送到远程仓库

将本地的分支推送到服务器:
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 removegit 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
$ git tag -d v1.1.1

将冒号前面的空值推送到远程标签名,从而高效地删除它:

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

检出标签

1
$ git checkout v1.0.0

检出标签会使你的仓库处于“分离头指针(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 # 或者 git switch 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 merge 命令后跟的分支

解决冲突后,通过 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):

  1. master分支:保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。
  2. develop 或者 next 的平行分支:用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master 分支了。
  3. 主题分支(短期分支):用于功能性开发,最终合并到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 cloneclone命令会自动地创建一个跟踪 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>
文章作者: Czm
文章链接: http://yoursite.com/2020/06/17/git%E7%9A%84%E4%BD%BF%E7%94%A8(%E4%BA%8C)/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Czm