Git 远程库——代码托管中心

初始化配置

以本地计算机的D:\GitWorkSpace Git 的工作目录,在其中新建一个项目文件夹MyFirstProject后打开。
image.png

  1. $ git init
  2. Initialized empty Git repository in D:/GitWorkSpace/MyFirstProject/.git/

执行命令git init后,将在33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject/.git/中完成对 Git 存储库的初始化。
查看.git文件夹的信息:

  1. $ ls -lA
  2. $ ll .git/

image.png
文件./.git/config用于记录该本地库的配置信息。

配置签名

签名由user.name(用户名)和user.email(Email 地址)组成,用于对不同开发者的身份作区分。包括项目/仓库级别、用户级别和系统级别 3 种类型。

用户名和 Email 地址与代码托管平台中远程库的验证信息无关; 项目/仓库级别与系统用户级别必须有一个设置生效。

项目/仓库级别

具有更高的优先级签名; 各个本地库的签名信息相互独立,互不干扰。

  1. git config user.name "Tully Monster"
  2. git config user.email abcd@xxx.com

配置文件的修改保存在:<Project>/.git/config文件中。
image.png

用户级别

若未设置项目/仓库级别的签名时,使用用户级别的签名。

  1. git config --global user.name "Tully Monster"
  2. git config --global user.email abcd@xxx.com

配置文件的修改保存在:~/.gitconfig文件中。
image.png

系统级别

若未设置用户级别的签名时,使用系统级别的签名。

git config --system [OPTION]
配置文件的修改保存在<Git_Root>\etc\gitconfig文件中。

配置编辑器

使用命令git config [--global | --system] core.editor [...]为 Git 的配置编辑器。

查看配置信息

使用命令git config --list查看 Git 的配置信息。

版本控制

在项目的master路径下执行命令git status查看当前项目路径的 Git 存储状态。

  1. git status

新的空项目

对于一个新的空项目:

  1. 33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
  2. $ git status
  3. On branch master
  4. No commits yet
  5. nothing to commit (create/copy files and use "git add" to track)

对于master分支,本地库暂未有任何被提交的内容、暂存区亦未有任何可提交的内容(可用git add命令追踪新建的文件)。

在项目中新建文件

在当前的master路径下(D:\GitWorkSpace\MyFirstProject)新建文件NewFile01.txt并写入下述内容:

2021-10-29
This is the 1st new file for Git.

查看状态

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        NewFile01.txt

nothing added to commit but untracked files present (use "git add" to track)

对于master分支,本地库暂未有任何被提交的内容、暂存区亦未有任何可提交的内容(可用git add命令追踪新建的文件),存在未追踪的文件NewFile01.txt(可用git add <file>...命令将文件载入暂存区以待提交)。

添加到暂存区

git add NewFile01.txt命令将文件NewFile01.txt添加到暂存区。

此时根据转换文本文件行尾换行的配置,默认按照 Windows 风格检出后用 Unix 的风格替换提交(将LF转换为CRLF),本地工作目录不受这一替换的影响。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git add NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   NewFile01.txt

对于master分支,本地库暂未有任何被提交的内容、暂存区有以下新文件的改变可被提交:NewFile01.txt(可用git rm --cached <file>...命令将文件撤出暂存区)。

从暂存区撤出文件的命令不会影响工作区的文件。

提交新建到本地库

git commit NewFile01.txt命令将文件NewFile01.txt提交到本地库。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git commit NewFile01.txt
hint: Waiting for your editor to close the file...

建议:等待编辑好 Git 提交的注释信息 (Git Commit Message) 后关闭文件以继续。

可以使用默认的 Vim 或 Visual Studio Code 编辑器等执行编辑。

image.png
在第一行写入注释信息:My first commit.
image.png

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git commit NewFile01.txt
[master (root-commit) 35797d6] My first commit.
 1 file changed, 2 insertions(+)
 create mode 100644 NewFile01.txt

master分支上创建了一个根提交(ID 号:35797d6)。注释内容为:My first commit.。这次提交修改/新建了 1 个文件,插入了 2 行内容。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git status
On branch master
nothing to commit, working tree clean

对于master分支,暂存区暂未有任何可提交的内容,工作目录的文件系统树完全一致。

修改项目文件内容

对文件NewFile01.txt做出 2 处修改后保存:

2021/10/29
This is the 1st new file for Git.
My second modification.

查看状态

查看修改后的 Git 状态:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git status
On branch master
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:   NewFile01.txt

no changes added to commit (use "git add" and/or "git commit -a")

对于master分支,存在未暂存的修改:NewFile01.txt(可用git add <file>...命令将文件更新到暂存区以待提交或用git restore <file>...命令丢弃工作目录的更改)。暂存区没有可提交的修改(可用git add命令将修改添加到暂存区或用git commit -a将修改暂存后立即提交)。

添加到暂存区

暂存修改:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git add NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   NewFile01.txt

提交修改到本地库

使用git commit NewFile01.txt -m "My second commit."命令提交修改到本地库,而不必单独用编辑器注释修改。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git commit NewFile01.txt -m "My second commit."
[master 13ac0b8] My second commit.
 1 file changed, 3 insertions(+), 2 deletions(-)

查看提交的版本记录

使用git log命令查看历史提交的版本记录:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git log
commit 13ac0b86148a10bbe5d7db28f5f273f3a3357eaa (HEAD -> master)
Author: Tully Monster <abcd@xxx.com>
Date:   Fri Oct 29 16:13:02 2021 +0800

    My second commit.

commit 35797d64b5b10ccc2a6db42d5bd946e4c273747b
Author: Tully Monster <abcd@xxx.com>
Date:   Fri Oct 29 15:25:15 2021 +0800

    My first commit.

每一个提交记录 (commit) 都有一个 hash 值作为提交记录的键,与提交人、提交时间以及提交注释对应。在当前的版本中,有(HEAD -> master)的标记,即用HEAD指针指向当前版本。

版本间的切换通过移动HEAD指针完成。

若日志信息太多,可用空格键向下翻页、B 键向上翻页、Q 键退出。
可用git log --pretty=oneline命令以每个提交历史仅占 1 行的方式显示日志;可用git log --oneline命令显示更简略的日志信息,此时只截取显示 40 位 hash 值的前 7 位;可用git reflog命令显示带HEAD指针移动次数的简略信息。

git reflog命令可显示HEAD指针前后的全部提交日志;其他日志查看命令只显示从当前版本往后的提交日志。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git log --pretty=oneline
13ac0b86148a10bbe5d7db28f5f273f3a3357eaa (HEAD -> master) My second commit.
35797d64b5b10ccc2a6db42d5bd946e4c273747b My first commit.

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git log --oneline
13ac0b8 (HEAD -> master) My second commit.
35797d6 My first commit.

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git reflog
13ac0b8 (HEAD -> master) HEAD@{0}: commit: My second commit.
35797d6 HEAD@{1}: commit (initial): My first commit.

版本的切换

版本前进后退的本质是HEAD指针的位置的移动。

版本直达

使用git reset --hard <hash_len_7>命令。

版本后退

使用git reset --hard HEAD[^...]执行版本的后退(每个^符号后退 1 版,不加^符号则恢复成当前指针所指位置的状态)。

使用git reset --hard HEAD~[NumberOfSteps]执行版本的前进(~符号后的数字注明了连续后退的步数)。

rest 命令的 3 个参数

使用git help <command>命令用浏览器查看特定命令的本地帮助文件,如git help reset

--soft

仅在本地库移动HEAD指针。
image.png

--mixed

在本地库移动HEAD指针,且重置暂存区。
image.png

--hard

在本地库移动HEAD指针,且重置暂存区和工作区。
image.png

文件的删除与找回

前提:文件存在时的状态提交到了本地库。
核心:

  1. 文件删除前已提交到本地库:git reset --hard <HistoricalRecords>
  2. 文件删除前未提交到本地库:git reset --hard HEAD

    创建待删除文件

    创建TestFileForDeletion.txt文件,并写入一行内容:This is a test file for deletion.
    image.png
    添加到暂存区后提交: ``` 33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git add TestFileForDeletion.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git commit -m “New a test file for deletion.” TestFileForDeletion.txt [master bdf55aa] New a test file for deletion. 1 file changed, 1 insertion(+) create mode 100644 TestFileForDeletion.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git status On branch master nothing to commit, working tree clean

<a name="Gutcu"></a>
### 删除文件
使用`rm TestFileForDeletion.txt`命令删除`TestFileForDeletion.txt`文件。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ rm TestFileForDeletion.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ ll total 1 -rw-r—r— 1 33891 197609 70 10月 29 17:33 NewFile01.txt

<a name="I7b7d"></a>
#### 删除后的状态

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git status On branch master Changes not staged for commit: (use “git add/rm …” to update what will be committed) (use “git restore …” to discard changes in working directory) deleted: TestFileForDeletion.txt

no changes added to commit (use “git add” and/or “git commit -a”)

<a name="qNhFh"></a>
#### 暂存并提交

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git add TestFileForDeletion.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git status On branch master Changes to be committed: (use “git restore —staged …” to unstage) deleted: TestFileForDeletion.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git commit -m “Delete the test file.” TestFileForDeletion.txt [master db5aff5] Delete the test file. 1 file changed, 1 deletion(-) delete mode 100644 TestFileForDeletion.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git status On branch master nothing to commit, working tree clean

<a name="OgLTj"></a>
### 找回文件
将版本回退到删除文件前的那个版本,即可完成对文件的找回。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git reflog db5aff5 (HEAD -> master) HEAD@{0}: commit: Delete the test file. bdf55aa HEAD@{1}: commit: New a test file for deletion. 13ac0b8 HEAD@{2}: reset: moving to 13ac0b8 35797d6 HEAD@{3}: reset: moving to 35797d6 13ac0b8 HEAD@{4}: reset: moving to 13ac0b8 35797d6 HEAD@{5}: reset: moving to 35797d6 13ac0b8 HEAD@{6}: reset: moving to 13ac0b8 35797d6 HEAD@{7}: reset: moving to 35797d6 35797d6 HEAD@{8}: reset: moving to 35797d6 13ac0b8 HEAD@{9}: commit: My second commit. 35797d6 HEAD@{10}: commit (initial): My first commit.

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git reset —hard HEAD^ HEAD is now at bdf55aa New a test file for deletion.

> 若文件的删除变化只添加 (`add`) 到了暂存区而未提交 (`commit`) 到本地库,则可使用`git reset --hard HEAD`命令找回文件。

<a name="J79CY"></a>
## 文件差异性比较
对于`New`文件,修改前:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ cat NewFile01.txt 2021/10/29 This is the 1st new file for Git. My second modification.

修改后:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ cat NewFile01.txt 2021年10月29日 This is the 1st new file for Git. My second modification. 新增一行。

使用`git diff <filename>`命令默认用于当前文件与暂存区对应文件的差异比较:
> 若使用`git diff <hash_len_7|HEAD|HEAD^[^...]> <filename>`命令,则可用于当前文件与特定历史版本或已暂存前文件的差异比较。
> 使用不带文件名的`diff`命令则可比较工作区的所有文件。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git diff diff —git a/NewFile01.txt b/NewFile01.txt index 23fb883..85da519 100644 —- a/NewFile01.txt +++ b/NewFile01.txt @@ -1,3 +1,4 @@ -2021/10/29 +2021年10月29日 This is the 1st new file for Git. -My second modification. \ No newline at end of file +My second modification. +新增一行。 \ No newline at end of file

![image.png](https://cdn.nlark.com/yuque/0/2021/png/932482/1635506797512-23b4c1fa-a8e4-4cc3-aa44-71711fbdd1d6.png#clientId=ua5d20060-f306-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=440&id=udaeb98e8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=586&originWidth=858&originalType=binary&ratio=1&rotation=0&showTitle=false&size=55450&status=done&style=none&taskId=u746acce8-1629-462b-905e-c965370ffe2&title=&width=644)
> Git 以行为单位管理文件的变化。

<a name="GSd96"></a>
#   分支管理
Git 分支是由指针管理起来的,可以快速创建、切换、合并与删除,适用于大型项目的开发。在分支上开发,调试后合并到主分支的策略使每个人的开发模块式相互独立不影响到其他人。

1. 主分支(默认的`master`分支)只用来发布重大版本更新(各版本可以有不同的标签以便于查找);
1. 日常开发应该在其他分支上完成,如`develop`;
1. 对于新增功能 (`feature`) 、用于预发布 (`release`) 、Bug 修复 (`bug`/`hot_fix`) 的临时性分支,应在使用完毕后及时删除,以免分支的混乱。
1. 多人开发时,可分别创建自己专属的分支,当阶段性工作完成后应该合并到上级分支。

![image.png](https://cdn.nlark.com/yuque/0/2021/png/932482/1635509293984-e08068aa-7057-4965-99cb-5c965691ca14.png#clientId=ua5d20060-f306-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=325&id=u9d8f1e1b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=650&originWidth=1769&originalType=binary&ratio=1&rotation=0&showTitle=false&size=151036&status=done&style=stroke&taskId=ud4cc86d5-dfd8-402f-b344-a4deb070c98&title=&width=884.5)
<a name="Yep8v"></a>
## 创建分支
使用`git branch <BranchName>`命令创建名为`<BranchName>`的新分支,如`git branch hot_fix`。
<a name="TearD"></a>
## 查看分支
使用`git branch -v`命令可查看分支的详细 (verbose) 信息(哈希值和名称)。

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ git branch -v hot_fix db5aff5 Delete the test file.

  • master db5aff5 Delete the test file. ```

    列出全部分支后,分支名称前以星号*标注的是当前分支。 当前分支已在各命令行的括号()中提及。

image.png

切换分支

使用git checkout <BranchName>切换到指定分支,如git checkout hot_fix
image.png

合并分支

hot_fix分支中产生修改:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ cat NewFile01.txt
2021/10/29
This is the 1st new file for Git.
My second modification. (Modified in branch hot_fix.)

使用git checkout master命令切换到接受合并的分支后,在使用git merge <BranchName>命令合并分支:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ git checkout master
Switched to branch 'master'

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git merge hot_fix
Updating db5aff5..2e131dd
Fast-forward
 NewFile01.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

分支合并的冲突产生

分支的同一位置同时发生不同的修改时,将在相互合并分支时产生冲突。需要执行手动的冲突解决。
hot_fix分支上修改,添加到暂存区后提交:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ cat NewFile01.txt
2021/10/29
This is the 1st new file for Git.
My second modification.

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ vim NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ cat NewFile01.txt
2021/10/29
This is the 1st new file for Git.
My second modification.
~~~

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ git add NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ git commit -m "Modified in branch hot_fix: add ~ at the last line" NewFile01.txt

[hot_fix bde3aae] Modified in branch hot_fix: add ~ at the last line
 1 file changed, 2 insertions(+), 1 deletion(-)

切换到master分支:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (hot_fix)
$ git checkout master
Switched to branch 'master'

master分支中的同一位置做出不同的修改,添加到暂存区后提交:

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ cat NewFile01.txt
2021/10/29
This is the 1st new file for Git.
My second modification. (Modified in branch hot_fix!)

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ vim NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ cat NewFile01.txt
2021/10/29
This is the 1st new file for Git.
My second modification.
!!!

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git add NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git commit -m "Modified in branch master: add git commit NewFile01.txt ! at the last line" NewFile01.txt
[master 8708adb] Modified in branch master: add git commit NewFile01.txt ! at the last line
 1 file changed, 2 insertions(+), 1 deletion(-)

尝试将hot_fix合并到master

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master)
$ git merge hot_fix
Auto-merging NewFile01.txt
CONFLICT (content): Merge conflict in NewFile01.txt
Automatic merge failed; fix conflicts and then commit the result.

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master|MERGING)
$

自动合并失败;需要手动修复冲突,然后提交结果。

分支合并的冲突解决

image.png

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master|MERGING)
$ ll
total 1
-rw-r--r-- 1 33891 197609 122 10月 29 21:35 NewFile01.txt

不同于 SVN,Git 产生冲突后,不会产生新的额外文件。

对于产生冲突的文件,Git 会在冲突发生出做出特定的标记:
image.png

  1. 编辑文件,删除特殊符号,把文件修改到满意为止后保存退出;
  2. 使用git add <filename>命令将此文件添加暂存区;
  3. 使用git commit -m "LogMessage"命令提交冲突修复(执行冲突修复时不能添加具体的文件名)。 ``` 33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master|MERGING) $ git add NewFile01.txt

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master|MERGING) $ git commit -m “Conflict resolved.” [master 47fa7f0] Conflict resolved.

33891@LeapingQuantum MINGW64 /d/GitWorkSpace/MyFirstProject (master) $ ```

删除分支