Git - 快速指南


Git - 基本概念

版本控制系统

版本控制系统 (VCS)是一种帮助软件开发人员协同工作并维护完整工作历史记录的软件。

下面列出了 VCS 的功能 -

  • 允许开发人员同时工作。
  • 不允许覆盖彼此的更改。
  • 维护每个版本的历史记录。

以下是 VCS 的类型 -

  • 集中版本控制系统(CVCS)。
  • 分布式/分散式版本控制系统(DVCS)。

在本章中,我们将只关注分布式版本控制系统,尤其是 Git。Git属于分布式版本控制系统。

分布式版本控制系统

集中版本控制系统(CVCS)使用中央服务器来存储所有文件并实现团队协作。但CVCS的主要缺点是它的单点故障,即中央服务器故障。不幸的是,如果中央服务器宕机一小时,那么在这一小时内,根本没有人可以协作。即使在最坏的情况下,如果中央服务器的磁盘损坏并且没有采取适当的备份,那么您将丢失项目的整个历史记录。这里,分布式版本控制系统(DVCS)应运而生。

DVCS 客户端不仅可以查看目录的最新快照,还可以完全镜像存储库。如果服务器出现故障,则可以将任何客户端的存储库复制回服务器以进行恢复。每次签出都是存储库的完整备份。Git 不依赖于中央服务器,这就是为什么您可以在离线时执行许多操作。您可以在离线状态下提交更改、创建分支、查看日志以及执行其他操作。您仅需要网络连接来发布更改并获取最新更改。

Git 的优点

免费和开源

Git 是在 GPL 的开源许可证下发布的。它可以通过互联网免费获得。您可以使用 Git 来管理房产项目,而无需支付一分钱。由于它是开源的,您可以下载其源代码并根据您的要求进行更改。

又快又小

由于大多数操作都是在本地执行的,因此在速度方面具有巨大的优势。Git 不依赖于中央服务器;这就是为什么每个操作都不需要与远程服务器交互。Git 的核心部分是用 C 编写的,这避免了与其他高级语言相关的运行时开销。尽管 Git 镜像了整个存储库,但客户端的数据量很小。这说明了Git在客户端压缩和存储数据的效率。

隐式备份

当存在多个数据副本时,丢失数据的可能性非常小。任何客户端上存在的数据都会镜像存储库,因此可以在发生崩溃或磁盘损坏时使用它。

安全

Git 使用称为安全哈希函数 (SHA1) 的常见加密哈希函数来命名和识别其数据库中的对象。每个文件和提交都会在签出时进行校验和并通过其校验和进行检索。这意味着,如果不了解 Git,就不可能更改 Git 数据库中的文件、日期、提交消息和任何其他数据。

无需强大的硬件

对于 CVCS,中央服务器需要足够强大才能满足整个团队的请求。对于较小的团队来说,这不是问题,但随着团队规模的增长,服务器的硬件限制可能会成为性能瓶颈。对于 DVCS,开发人员不会与服务器交互,除非他们需要推送或拉取更改。所有繁重的工作都发生在客户端,因此服务器硬件确实可以非常简单。

更容易分支

CVCS使用廉价的复制机制,如果我们创建一个新分支,它会将所有代码复制到新分支,因此非常耗时且效率不高。此外,CVCS中分支的删除和合并是复杂且耗时的。但是使用 Git 进行分支管理非常简单。创建、删除和合并分支只需要几秒钟。

DVCS 术语

本地存储库

每个 VCS 工具都提供一个私人工作场所作为工作副本。开发人员在其私人工作场所进行更改,提交后,这些更改将成为存储库的一部分。Git 更进一步,为他们提供了整个存储库的私有副本。用户可以使用此存储库执行许多操作,例如添加文件、删除文件、重命名文件、移动文件、提交更改等等。

工作目录和暂存区或索引

工作目录是检出文件的地方。在其他 CVCS 中,开发人员通常进行修改并将更改直接提交到存储库。但 Git 使用了不同的策略。Git 不会跟踪每个修改过的文件。每当您提交操作时,Git 都会查找暂存区域中存在的文件。仅考虑提交暂存区域中存在的那些文件,而不考虑所有修改的文件。

让我们看看Git的基本工作流程。

步骤 1 - 您修改工作目录中的文件。

步骤 2 - 将这些文件添加到暂存区域。

步骤 3 - 您执行提交操作,将文件从暂存区域移出。推送操作后,它将更改永久存储到 Git 存储库。

Git 教程

假设您修改了两个文件,即“sort.c”和“search.c”,并且您希望每个操作有两个不同的提交。您可以在暂存区添加一个文件并进行提交。第一次提交后,对另一个文件重复相同的过程。

# First commit
[bash]$ git add sort.c

# adds file to the staging area
[bash]$ git commit –m “Added sort operation”

# Second commit
[bash]$ git add search.c

# adds file to the staging area
[bash]$ git commit –m “Added search operation”

斑点

Blob代表二进制对象。_ 文件的每个版本都由 blob 表示。Blob 保存文件数据,但不包含有关该文件的任何元数据。它是一个二进制文件,在 Git 数据库中,它被命名为该文件的 SHA1 哈希值。在 Git 中,文件不是通过名称来寻址的。一切都是针对内容的。

树木

树是一个对象,它代表一个目录。它包含 blob 以及其他子目录。树是一个二进制文件,存储对 blob 和树的引用,也称为树对象的SHA1哈希值。

提交

提交保存存储库的当前状态。提交也由SHA1哈希命名。您可以将提交对象视为链表的一个节点。每个提交对象都有一个指向父提交对象的指针。从给定的提交中,您可以通过查看父指针来回溯以查看提交的历史记录。如果一个提交有多个父提交,则该特定提交是通过合并两个分支创建的。

分支机构

分支用于创建另一条开发线。默认情况下,Git 有一个 master 分支,与 Subversion 中的 trunk 相同。通常,创建一个分支是为了处理新功能。一旦功能完成,它就会与主分支合并,然后我们删除该分支。每个分支都由 HEAD 引用,它指向分支中的最新提交。每当您进行提交时,HEAD 都会更新为最新的提交。

标签

标签为存储库中的特定版本分配一个有意义的名称。标签与分支非常相似,但不同之处在于标签是不可变的。这意味着,标签是一个分支,没有人打算修改它。一旦为特定提交创建了标签,即使您创建新的提交,它也不会被更新。通常,开发人员为产品发布创建标签。

克隆

克隆操作创建存储库的实例。克隆操作不仅会检查工作副本,还会镜像完整的存储库。用户可以使用此本地存储库执行许多操作。唯一涉及网络的时间是同步存储库实例时。

拉操作将更改从远程存储库实例复制到本地存储库实例。拉取操作用于两个存储库实例之间的同步。这与 Subversion 中的更新操作相同。

推送操作将更改从本地存储库实例复制到远程存储库实例。这用于将更改永久存储到 Git 存储库中。这与 Subversion 中的提交操作相同。

HEAD 是一个指针,它始终指向分支中最新的提交。每当您进行提交时,HEAD 都会更新为最新的提交。分支的头存储在.git/refs/heads/目录中。

[CentOS]$ ls -1 .git/refs/heads/
master

[CentOS]$ cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49

修订

修订版代表源代码的版本。Git 中的修订由提交表示。这些提交由SHA1安全哈希值标识。

网址

URL 表示 Git 存储库的位置。Git URL 存储在配置文件中。

[tom@CentOS tom_repo]$ pwd
/home/tom/tom_repo

[tom@CentOS tom_repo]$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = gituser@git.server.com:project.git
fetch = +refs/heads/*:refs/remotes/origin/*

Git - 环境设置

在使用 Git 之前,您必须安装并进行一些基本配置更改。以下是在 Ubuntu 和 Centos Linux 上安装 Git 客户端的步骤。

Git客户端的安装

如果您使用 Debian 基础 GNU/Linux 发行版,那么apt-get命令将完成所需的操作。

[ubuntu ~]$ sudo apt-get install git-core
[sudo] password for ubuntu:

[ubuntu ~]$ git --version
git version 1.8.1.2

如果您使用基于 RPM 的 GNU/Linux 发行版,则使用给定的yum命令。

[CentOS ~]$
su -
Password:

[CentOS ~]# yum -y install git-core

[CentOS ~]# git --version
git version 1.7.1

自定义 Git 环境

Git 提供了 git config 工具,它允许您设置配置变量。Git 将所有全局配置存储在.gitconfig文件中,该文件位于您的主目录中。要将这些配置值设置为全局,请添加--global选项,如果省略--global选项,则您的配置特定于当前 Git 存储库。

您还可以设置系统范围的配置。Git 将这些值存储在/etc/gitconfig文件中,该文件包含系统上每个用户和存储库的配置。要设置这些值,您必须具有 root 权限并使用--system选项。

当上面的代码被编译并执行时,它会产生以下结果 -

设置用户名

Git 在每次提交时都会使用此信息。

[jerry@CentOS project]$ git config --global user.name "Jerry Mouse"

设置电子邮件 ID

Git 在每次提交时都会使用此信息。

[jerry@CentOS project]$ git config --global user.email "jerry@tutorialspoint.com"

避免拉取时合并提交

您从远程存储库中提取最新的更改,如果这些更改不一致,则默认情况下 Git 会创建合并提交。我们可以通过以下设置来避免这种情况。

jerry@CentOS project]$ git config --global branch.autosetuprebase always

颜色突出显示

以下命令在控制台中启用 Git 的颜色突出显示。

[jerry@CentOS project]$ git config --global color.ui true

[jerry@CentOS project]$ git config --global color.status auto

[jerry@CentOS project]$ git config --global color.branch auto

设置默认编辑器

默认情况下,Git 使用系统默认编辑器,该编辑器取自 VISUAL 或 EDITOR 环境变量。我们可以使用 git config 配置不同的一个。

[jerry@CentOS project]$ git config --global core.editor vim

设置默认合并工具

Git 不提供默认的合并工具来将冲突的更改集成到工作树中。我们可以通过启用以下设置来设置默认合并工具。

[jerry@CentOS project]$ git config --global merge.tool vimdiff

列出 Git 设置

要验证本地存储库的 Git 设置,请使用git config –list命令,如下所示。

[jerry@CentOS ~]$ git config --list

上述命令将产生以下结果。

user.name=Jerry Mouse
user.email=jerry@tutorialspoint.com
push.default=nothing
branch.autosetuprebase=always
color.ui=true
color.status=auto
color.branch=auto
core.editor=vim
merge.tool=vimdiff

Git - 生命周期

在本章中,我们将讨论 Git 的生命周期。在后面的章节中,我们将介绍每个操作的 Git 命令。

一般工作流程如下 -

  • 您将 Git 存储库克隆为工作副本。

  • 您可以通过添加/编辑文件来修改工作副本。

  • 如有必要,您还可以通过采用其他开发人员的更改来更新工作副本。

  • 您在提交之前检查更改。

  • 您提交更改。如果一切正常,那么您将更改推送到存储库。

  • 提交后,如果您意识到出现问题,则更正上次提交并将更改推送到存储库。

下图是工作流程的图示。

Git 教程

Git - 创建操作

在本章中,我们将了解如何创建远程 Git 存储库;从现在开始,我们将其称为 Git Server。我们需要一个 Git 服务器来允许团队协作。

创建新用户

# add new group
[root@CentOS ~]# groupadd dev

# add new user
[root@CentOS ~]# useradd -G devs -d /home/gituser -m -s /bin/bash gituser

# change password
[root@CentOS ~]# passwd gituser

上述命令将产生以下结果。

Changing password for user gituser.
New password:
Retype new password:
passwd: all authentication token updated successfully.

创建裸存储库

让我们使用init命令和--bare选项来初始化一个新的存储库。它在没有工作目录的情况下初始化存储库。按照约定,裸存储库必须命名为.git

[gituser@CentOS ~]$ pwd
/home/gituser

[gituser@CentOS ~]$ mkdir project.git

[gituser@CentOS ~]$ cd project.git/

[gituser@CentOS project.git]$ ls

[gituser@CentOS project.git]$ git --bare init
Initialized empty Git repository in /home/gituser-m/project.git/

[gituser@CentOS project.git]$ ls
branches config description HEAD hooks info objects refs

生成公共/私有 RSA 密钥对

让我们逐步了解一下配置 Git 服务器的过程,ss​​h-keygen实用程序会生成公共/私有 RSA 密钥对,我们将使用它来进行用户身份验证。

打开终端并输入以下命令,然后每次输入时按 Enter 键。成功完成后,它将在主目录中创建一个.ssh目录。

tom@CentOS ~]$ pwd
/home/tom

[tom@CentOS ~]$ ssh-keygen

上述命令将产生以下结果。

Generating public/private rsa key pair.
Enter file in which to save the key (/home/tom/.ssh/id_rsa): Press Enter Only
Created directory '/home/tom/.ssh'.
Enter passphrase (empty for no passphrase): ---------------> Press Enter Only
Enter same passphrase again: ------------------------------> Press Enter Only
Your identification has been saved in /home/tom/.ssh/id_rsa.
Your public key has been saved in /home/tom/.ssh/id_rsa.pub.
The key fingerprint is:
df:93:8c:a1:b8:b7:67:69:3a:1f:65:e8:0e:e9:25:a1 tom@CentOS
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
|
.
|
| Soo |
| o*B. |
| E = *.= |
| oo==. . |
| ..+Oo
|
+-----------------+

ssh-keygen生成了两个密钥,第一个是私有密钥(即 id_rsa),第二个是公共密钥(即 id_rsa.pub)。

注意:切勿与他人分享您的私钥。

将密钥添加到authorized_keys

假设有两个开发人员正在开发一个项目,即 Tom 和 Jerry。两个用户都生成了公钥。让我们看看如何使用这些密钥进行身份验证。

Tom 使用ssh-copy-id命令将他的公钥添加到服务器,如下所示 -

[tom@CentOS ~]$ pwd
/home/tom

[tom@CentOS ~]$ ssh-copy-id -i ~/.ssh/id_rsa.pub gituser@git.server.com

上述命令将产生以下结果。

gituser@git.server.com's password:
Now try logging into the machine, with "ssh 'gituser@git.server.com'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

同样,Jerry 使用 ssh-copy-id 命令将他的公钥添加到服务器。

[jerry@CentOS ~]$ pwd
/home/jerry

[jerry@CentOS ~]$ ssh-copy-id -i ~/.ssh/id_rsa gituser@git.server.com

上述命令将产生以下结果。

gituser@git.server.com's password:
Now try logging into the machine, with "ssh 'gituser@git.server.com'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

将更改推送到存储库

我们在服务器上创建了一个裸存储库并允许两个用户访问。从现在开始,Tom 和 Jerry 可以通过将存储库添加为远程来将其更改推送到存储库。

Git init 命令每次从.git/config文件读取配置时都会创建.git目录来存储有关存储库的元数据。

Tom 创建一个新目录,添加 README 文件,并将其更改作为初始提交提交。提交后,他通过运行git log命令来验证提交消息。

[tom@CentOS ~]$ pwd
/home/tom

[tom@CentOS ~]$ mkdir tom_repo

[tom@CentOS ~]$ cd tom_repo/

[tom@CentOS tom_repo]$ git init
Initialized empty Git repository in /home/tom/tom_repo/.git/

[tom@CentOS tom_repo]$ echo 'TODO: Add contents for README' > README

[tom@CentOS tom_repo]$ git status -s
?? README

[tom@CentOS tom_repo]$ git add .

[tom@CentOS tom_repo]$ git status -s
A README

[tom@CentOS tom_repo]$ git commit -m 'Initial commit'

上述命令将产生以下结果。

[master (root-commit) 19ae206] Initial commit
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 README

Tom 通过执行 git log 命令来检查日志消息。

[tom@CentOS tom_repo]$ git log

上述命令将产生以下结果。

commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Tom 将其更改提交到本地存储库。现在,是时候将更改推送到远程存储库了。但在此之前,我们必须将存储库添加为远程存储库,这是一次性操作。之后,他可以安全地将更改推送到远程存储库。

注意- 默认情况下,Git 仅推送到匹配的分支:对于本地端存在的每个分支,如果远程端已存在同名分支,则远程端会更新。在我们的教程中,每次我们将更改推送到原始主分支时,请根据您的要求使用适当的分支名称。

[tom@CentOS tom_repo]$ git remote add origin gituser@git.server.com:project.git

[tom@CentOS tom_repo]$ git push origin master

上述命令将产生以下结果。

Counting objects: 3, done.
Writing objects: 100% (3/3), 242 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
* [new branch]
master −> master

现在,更改已成功提交到远程存储库。

Git - 克隆操作

我们在 Git 服务器上有一个裸存储库,Tom 也推送了他的第一个版本。现在,Jerry 可以查看他的更改。克隆操作创建远程存储库的实例。

Jerry 在他的主目录中创建一个新目录并执行克隆操作。

[jerry@CentOS ~]$ mkdir jerry_repo

[jerry@CentOS ~]$ cd jerry_repo/

[jerry@CentOS jerry_repo]$ git clone gituser@git.server.com:project.git

上述命令将产生以下结果。

Initialized empty Git repository in /home/jerry/jerry_repo/project/.git/
remote: Counting objects: 3, done.
Receiving objects: 100% (3/3), 241 bytes, done.
remote: Total 3 (delta 0), reused 0 (delta 0)

Jerry 将目录更改为新的本地存储库并列出其目录内容。

[jerry@CentOS jerry_repo]$ cd project/

[jerry@CentOS jerry_repo]$ ls
README

Git - 执行更改

Jerry 克隆存储库并决定实现基本的字符串操作。所以他创建了 string.c 文件。添加内容后,string.c 将如下所示 -

#include <stdio.h>

int my_strlen(char *s)
{
   char *p = s;

   while (*p)
      ++p;

   return (p - s);
}

int main(void)
{
   int i;
   char *s[] = 
   {
      "Git tutorials",
      "Tutorials Point"
   };

   for (i = 0; i < 2; ++i)
      
   printf("string lenght of %s = %d\n", s[i], my_strlen(s[i]));

   return 0;
}

他编译并测试了他的代码,一切正常。现在,他可以安全地将这些更改添加到存储库中。

Git add 操作将文件添加到暂存区。

[jerry@CentOS project]$ git status -s
?? string
?? string.c

[jerry@CentOS project]$ git add string.c

Git 在文件名前显示一个问号。显然,这些文件不是 Git 的一部分,这就是为什么 Git 不知道如何处理这些文件。这就是为什么 Git 在文件名前显示一个问号。

Jerry 已将文件添加到存储区域,git status 命令将显示暂存区域中存在的文件。

[jerry@CentOS project]$ git status -s
A string.c
?? string

为了提交更改,他使用了 git commit 命令,后跟 –m 选项。如果我们省略 –m 选项。Git 将打开一个文本编辑器,我们可以在其中编写多行提交消息。

[jerry@CentOS project]$ git commit -m 'Implemented my_strlen function'

上述命令将产生以下结果 -

[master cbe1249] Implemented my_strlen function
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c

提交查看日志详细信息后,他运行 git log 命令。它将显示所有提交的信息,包括提交 ID、提交作者、提交日期和提交的SHA-1哈希值。

[jerry@CentOS project]$ git log

上述命令将产生以下结果 -

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Git - 审查更改

查看提交详细信息后,Jerry 意识到字符串长度不能为负数,这就是他决定更改 my_strlen 函数的返回类型的原因。

Jerry 使用git log命令查看日志详细信息。

[jerry@CentOS project]$ git log

上述命令将产生以下结果。

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function

Jerry 使用git show命令查看提交详细信息。git show 命令采用SHA-1提交 ID 作为参数。

[jerry@CentOS project]$ git show cbe1249b140dad24b2c35b15cc7e26a6f02d2277

上述命令将产生以下结果 -

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


diff --git a/string.c b/string.c
new file mode 100644
index 0000000..187afb9
--- /dev/null
+++ b/string.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int my_strlen(char *s)
+{
   +
   char *p = s;
   +
   +
   while (*p)
   + ++p;
   + return (p -s );
   +
}
+

他将函数的返回类型从 int 更改为 size_t。测试代码后,他通过运行git diff命令来检查更改。

[jerry@CentOS project]$ git diff

上述命令将产生以下结果 -

diff --git a/string.c b/string.c
index 187afb9..7da2992 100644
--- a/string.c
+++ b/string.c
@@ -1,6 +1,6 @@
#include <stdio.h>

-int my_strlen(char *s)
+size_t my_strlen(char *s)
{
   char *p = s;
   @@ -18,7 +18,7 @@ int main(void)
};
for (i = 0; i < 2; ++i)
{
   - printf("string lenght of %s = %d\n", s[i], my_strlen(s[i]));
   + printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
   return 0;
}

Git diff 在新添加的行前显示“+”号,在删除的行前显示“-”号。

Git - 提交更改

Jerry 已经提交了更改,并且他想更正他的上一次提交。在这种情况下,git amend操作会有所帮助。修改操作更改最后一次提交,包括您的提交消息;它创建一个新的提交 ID。

在修改操作之前,他会检查提交日志。

[jerry@CentOS project]$ git log

上述命令将产生以下结果。

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Jerry 使用 --amend 操作提交新的更改并查看提交日志。

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git add string.c

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git commit --amend -m 'Changed return type of my_strlen to size_t'
[master d1e19d3] Changed return type of my_strlen to size_t
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c

现在,git log 将显示带有新提交 ID 的新提交消息 -

[jerry@CentOS project]$ git log

上述命令将产生以下结果。

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Git - 推送操作

Jerry 通过使用修改操作修改了他的上一次提交,并且他准备好推送更改。Push操作将数据永久存储到Git存储库中。推送操作成功后,其他开发者就可以看到Jerry的变化。

他执行 git log 命令来查看提交详细信息。

[jerry@CentOS project]$ git log

上述命令将产生以下结果:

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t

在推送操作之前,他想查看自己的更改,因此他使用git show命令来查看自己的更改。

[jerry@CentOS project]$ git show d1e19d316224cddc437e3ed34ec3c931ad803958

上述命令将产生以下结果:

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t

diff --git a/string.c b/string.c
new file mode 100644
index 0000000..7da2992
--- /dev/null
+++ b/string.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+size_t my_strlen(char *s)
+
{
   +
   char *p = s;
   +
   +
   while (*p)
   + ++p;
   + return (p -s );
   +
}
+
+int main(void)
+
{
   + int i;
   + char *s[] = 
   {
      + "Git tutorials",
      + "Tutorials Point"
      +
   };
   +
   +
   +
   for (i = 0; i < 2; ++i)
   printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
   +
   +
   return 0;
   +
}

杰瑞对他的改变感到满意,并准备好推动他的改变。

[jerry@CentOS project]$ git push origin master

上述命令将产生以下结果:

Counting objects: 4, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 517 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
19ae206..d1e19d3 master −> master

Jerry的更改已成功推送到存储库;现在其他开发人员可以通过执行克隆或更新操作来查看他的更改。

Git - 更新操作

修改现有功能

Tom 执行克隆操作并找到一个新文件 string.c。他想知道是谁将此文件添加到存储库中以及出于什么目的,因此,他执行了git log命令。

[tom@CentOS ~]$ git clone gituser@git.server.com:project.git

上述命令将产生以下结果 -

Initialized empty Git repository in /home/tom/project/.git/
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
Receiving objects: 100% (6/6), 726 bytes, done.
remote: Total 6 (delta 0), reused 0 (delta 0)

克隆操作将在当前工作目录中创建一个新目录。他将目录更改为新创建的目录并执行git log命令。

[tom@CentOS ~]$ cd project/

[tom@CentOS project]$ git log

上述命令将产生以下结果 -

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

通过观察日志,他发现string.c这个文件是Jerry添加的,用于实现基本的字符串操作。他对杰瑞的代码很好奇。于是他在文本编辑器中打开 string.c 并立即发现了一个错误。在 my_strlen 函数中,Jerry 没有使用常量指针。因此,他决定修改 Jerry 的代码。修改后,代码如下 -

[tom@CentOS project]$ git diff

上述命令将产生以下结果 -

diff --git a/string.c b/string.c
index 7da2992..32489eb 100644
--- a/string.c
+++ b/string.c
@@ -1,8 +1,8 @@
#include <stdio.h>
-size_t my_strlen(char *s)
+size_t my_strlen(const char *s)
{
   - char *p = s;
   + const char *p = s;
   while (*p)
   ++p;
}

测试后,他提交了更改。

[tom@CentOS project]$ git status -s
M string.c
?? string

[tom@CentOS project]$ git add string.c

[tom@CentOS project]$ git commit -m 'Changed char pointer to const char pointer'
[master cea2c00] Changed char pointer to const char pointer
1 files changed, 2 insertions(+), 2 deletions(-)

[tom@CentOS project]$ git log

上述命令将产生以下结果 -

commit cea2c000f53ba99508c5959e3e12fff493b
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 08:32:07 2013 +0530

Changed char pointer to const char pointer


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit

Tom 使用 git push 命令来推送他的更改。

[tom@CentOS project]$ git push origin master

上述命令将产生以下结果 -

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 336 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
d1e19d3..cea2c00 master −> master

添加新功能

与此同时,Jerry 决定实现字符串比较功能。所以他修改了string.c。修改后,文件如下所示 -

[jerry@CentOS project]$ git diff

上述命令将产生以下结果 -

index 7da2992..bc864ed 100644
--- a/string.c
+++ b/string.c
30Git Tutorials
@@ -9,9 +9,20 @@ size_t my_strlen(char *s)
return (p -s );
}
+char *my_strcpy(char *t, char *s)
+
{
   +
   char *p = t;
   +
   + while (*t++ = *s++)
   + ;
   +
   +
   return p;
   +
}
+
int main(void)
{
   int i; 
   +
   char p1[32];
   char *s[] = 
   {
      "Git tutorials",
      "Tutorials Point"
      @@ -20,5 +31,7 @@ int main(void)
      for (i = 0; i < 2; ++i)
      printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
      +
      printf("%s\n", my_strcpy(p1, "Hello, World !!!"));
      +
      return 0;
   }
}

经过测试后,他准备好推动他的改变。

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git add string.c

[jerry@CentOS project]$ git commit -m "Added my_strcpy function"
[master e944e5a] Added my_strcpy function
1 files changed, 13 insertions(+), 0 deletions(-)

在推送操作之前,他通过查看日志消息来验证提交。

[jerry@CentOS project]$ git log

上述命令将产生以下结果 -

commit e944e5aab74b26e7447d3281b225309e4e59efcd
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:41:42 2013 +0530

Added my_strcpy function


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

杰瑞对这些变化感到满意,他想推动他的变化。

[jerry@CentOS project]$ git push origin master

上述命令将产生以下结果 -

To gituser@git.server.com:project.git
! [rejected]
master −> master (non-fast-forward)
error: failed to push some refs to 'gituser@git.server.com:project.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.

但 Git 不允许 Jerry 推动他的更改。因为Git发现远程仓库和Jerry的本地仓库不同步。因此,他可能会丢失该项目的历史记录。为了避免这种混乱,Git 失败了此操作。现在,Jerry 必须首先更新本地存储库,然后才能推送自己的更改。

获取最新更改

Jerry 执行 git pull 命令将本地存储库与远程存储库同步。

[jerry@CentOS project]$ git pull

上述命令将产生以下结果 -

remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
d1e19d3..cea2c00 master −> origin/master
First, rewinding head to replay your work on top of it...
Applying: Added my_strcpy function

拉取操作后,Jerry 检查日志消息并找到 Tom 提交的详细信息,提交 ID 为cea2c000f53ba99508c5959e3e12fff493ba6f69

[jerry@CentOS project]$ git log

上述命令将产生以下结果 -

commit e86f0621c2a3f68190bba633a9fe6c57c94f8e4f
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:41:42 2013 +0530

Added my_strcpy function


commit cea2c000f53ba99508c5959e3e12fff493ba6f69
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 08:32:07 2013 +0530

Changed char pointer to const char pointer


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit

现在,Jerry 的本地存储库已与远程存储库完全同步。这样他就可以安全地推动他的改变。

[jerry@CentOS project]$ git push origin master

上述命令将产生以下结果 -

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 455 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
cea2c00..e86f062 master −> master

Git - 存储操作

假设您正在为您的产品实现一项新功能。您的代码正在进行中,突然出现客户升级。因此,您必须将新功能的工作搁置几个小时。您不能提交部分代码,也不能放弃您的更改。因此,您需要一些临时空间,可以在其中存储部分更改并稍后提交。

在 Git 中,存储操作会获取修改后的跟踪文件、暂存更改,并将它们保存在一堆未完成的更改中,以便您可以随时重新应用。

[jerry@CentOS project]$ git status -s
M string.c
?? string

现在,您想要切换分支以进行客户升级,但您不想提交您一直在做的事情;所以你会隐藏更改。要将新的存储推入堆栈,请运行git stash命令。

[jerry@CentOS project]$ git stash
Saved working directory and index state WIP on master: e86f062 Added my_strcpy function
HEAD is now at e86f062 Added my_strcpy function

现在,您的工作目录是干净的,所有更改都保存在堆栈中。让我们用git status命令来验证一下。

[jerry@CentOS project]$ git status -s
?? string

现在您可以安全地切换分支并在其他地方工作。我们可以使用git stash list命令查看隐藏更改的列表。

[jerry@CentOS project]$ git stash list
stash@{0}: WIP on master: e86f062 Added my_strcpy function

假设您已经解决了客户升级问题,并且您回到新功能上寻找半成品代码,只需执行git stash pop命令,即可从堆栈中删除更改并将它们放入当前工作目录中。

[jerry@CentOS project]$ git status -s
?? string

[jerry@CentOS project]$ git stash pop

上述命令将产生以下结果:

# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
#
modified: string.c
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
#
string
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (36f79dfedae4ac20e2e8558830154bd6315e72d4)

[jerry@CentOS project]$ git status -s
M string.c
?? string

Git - 移动操作

顾名思义,移动操作将目录或文件从一个位置移动到另一个位置。Tom 决定将源代码移至src目录中。修改后的目录结构将如下所示 -

[tom@CentOS project]$ pwd
/home/tom/project

[tom@CentOS project]$ ls
README string string.c

[tom@CentOS project]$ mkdir src

[tom@CentOS project]$ git mv string.c src/

[tom@CentOS project]$ git status -s
R string.c −> src/string.c
?? string

为了使这些更改永久化,我们必须将修改后的目录结构推送到远程存储库,以便其他开发人员可以看到它。

[tom@CentOS project]$ git commit -m "Modified directory structure"

[master 7d9ea97] Modified directory structure
1 files changed, 0 insertions(+), 0 deletions(-)
rename string.c => src/string.c (100%)

[tom@CentOS project]$ git push origin master
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 320 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
e86f062..7d9ea97 master −> master

在Jerry的本地存储库中,在pull操作之前,它会显示旧的目录结构。

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project

[jerry@CentOS project]$ ls
README string string.c

但拉取操作后,目录结构将会更新。现在,Jerry 可以看到src目录以及该目录中存在的文件。

[jerry@CentOS project]$ git pull
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
e86f062..7d9ea97 master −> origin/master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 7d9ea97683da90bcdb87c28ec9b4f64160673c8a.

[jerry@CentOS project]$ ls
README src string

[jerry@CentOS project]$ ls src/
string.c

Git - 重命名操作

到目前为止,Tom 和 Jerry 都使用手动命令来编译他们的项目。现在,Jerry 决定为他们的项目创建 Makefile,并为文件“string.c”指定一个正确的名称。

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project

[jerry@CentOS project]$ ls
README src

[jerry@CentOS project]$ cd src/

[jerry@CentOS src]$ git add Makefile

[jerry@CentOS src]$ git mv string.c string_operations.c

[jerry@CentOS src]$ git status -s
A Makefile
R string.c −> string_operations.c

Git 在文件名前显示R表示该文件已被重命名。

对于提交操作,Jerry 使用了 -a 标志,这使得 git commit 自动检测修改的文件。

[jerry@CentOS src]$ git commit -a -m 'Added Makefile and renamed strings.c to
string_operations.c '

[master 94f7b26] Added Makefile and renamed strings.c to string_operations.c
1 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 src/Makefile
rename src/{string.c => string_operations.c} (100%)

提交后,他将更改推送到存储库。

[jerry@CentOS src]$ git push origin master

上述命令将产生以下结果 -

Counting objects: 6, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 396 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
7d9ea97..94f7b26 master −> master

现在,其他开发人员可以通过更新其本地存储库来查看这些修改。

Git - 删除操作

Tom 更新他的本地存储库并在src目录中找到编译后的二进制文件。查看提交消息后,他意识到编译后的二进制文件是由 Jerry 添加的。

[tom@CentOS src]$ pwd
/home/tom/project/src

[tom@CentOS src]$ ls
Makefile string_operations string_operations.c

[tom@CentOS src]$ file string_operations
string_operations: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses
shared libs), for GNU/Linux 2.6.18, not stripped

[tom@CentOS src]$ git log
commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

VCS 仅用于存储源代码而不是可执行二进制文件。因此,Tom 决定从存储库中删除该文件。为了进一步操作,他使用了git rm命令。

[tom@CentOS src]$ ls
Makefile string_operations string_operations.c

[tom@CentOS src]$ git rm string_operations
rm 'src/string_operations'

[tom@CentOS src]$ git commit -a -m "Removed executable binary"

[master 5776472] Removed executable binary
1 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100755 src/string_operations

提交后,他将更改推送到存储库。

[tom@CentOS src]$ git push origin master

上述命令将产生以下结果。

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 310 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
29af9d4..5776472 master −> master

Git - 修复错误

人非圣贤孰能。因此,每个 VCS 都提供了修复错误的功能,直到达到某一点为止。Git 提供了一个功能,我们可以使用它来撤消对本地存储库所做的修改。

假设用户不小心对其本地存储库进行了一些更改,然后想要撤消这些更改。在这种情况下,恢复操作就发挥着重要作用。

恢复未提交的更改

让我们假设 Jerry 不小心修改了本地存储库中的文件。但他想撤消他的修改。为了处理这种情况,我们可以使用git checkout命令。我们可以使用此命令来恢复文件的内容。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git checkout string_operations.c

[jerry@CentOS src]$ git status –s

此外,我们可以使用git checkout命令从本地存储库中获取已删除的文件。让我们假设 Tom 从本地存储库中删除了一个文件,并且我们希望恢复该文件。我们可以使用相同的命令来实现这一点。

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ rm string_operations.c

[tom@CentOS src]$ ls -1
Makefile

[tom@CentOS src]$ git status -s
D string_operations.c

Git在文件名前显示字母D。这表明该文件已从本地存储库中删除。

[tom@CentOS src]$ git checkout string_operations.c

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ git status -s

注意- 我们可以在提交之前执行所有这些操作。

从暂存区删除更改

我们已经看到,当我们执行添加操作时,文件从本地存储库移动到声明区域。如果用户意外修改了文件并将其添加到暂存区域,他可以使用git checkout命令恢复更改。

在 Git 中,有一个 HEAD 指针始终指向最新的提交。如果你想撤销暂存区的更改,那么你可以使用 git checkout 命令,但使用 checkout 命令时,你必须提供一个额外的参数,即 HEAD 指针。附加的提交指针参数指示 git checkout 命令重置工作树并删除暂存的更改。

让我们假设 Tom 修改了他本地存储库中的一个文件。如果我们查看该文件的状态,会显示该文件已被修改但未添加到暂存区。

tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
# Unmodified file

[tom@CentOS src]$ git status -s

# Modify file and view it’s status.
[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

Git status 显示该文件存在于暂存区域中,现在使用 git checkout 命令将其恢复并查看恢复的文件的状态。

[tom@CentOS src]$ git checkout HEAD -- string_operations.c

[tom@CentOS src]$ git status -s

使用 Git Reset 移动 HEAD 指针

进行一些更改后,您可能决定删除这些更改。Git重置命令用于重置或恢复更改。我们可以执行三种不同类型的重置操作。

下图显示了 Git 重置命令的图示。

git 教程 git 教程

柔软的

每个分支都有一个 HEAD 指针,它指向最新的提交。如果我们使用带有--soft选项的Git重置命令,后跟提交ID,那么它只会重置HEAD指针,而不会破坏任何东西。

.git/refs/heads/master文件存储 HEAD 指针的提交 ID。我们可以使用git log -1命令来验证。

[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1

现在,查看最新的提交 ID,它将与上面的提交 ID 匹配。

[jerry@CentOS project]$ git log -2

上述命令将产生以下结果。

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary


commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

让我们重置 HEAD 指针。

[jerry@CentOS project]$ git reset --soft HEAD~

现在,我们只需将 HEAD 指针重置回一个位置。让我们检查.git/refs/heads/master 文件的内容。

[jerry@CentOS project]$ cat .git/refs/heads/master
29af9d45947dc044e33d69b9141d8d2dad37cc62

文件中的提交 ID 已更改,现在通过查看提交消息来验证它。

jerry@CentOS project]$ git log -2

上述命令将产生以下结果。

commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary


commit 94f7b26005f856f1a1b733ad438e97a0cd509c1a
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:08:01 2013 +0530

Added Makefile and renamed strings.c to string_operations.c

混合的

使用 --mixed 选项进行 Git 重置会从暂存区域恢复尚未提交的更改。它仅恢复暂存区域中的更改。对文件工作副本所做的实际更改不受影响。默认的Git重置相当于git重置--mixed。

难的

如果您在 Git Reset 命令中使用 --hard 选项,它将清除暂存区域;它会将 HEAD 指针重置为特定提交 ID 的最新提交,并删除本地文件更改。

让我们检查提交 ID。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git log -1

上述命令将产生以下结果。

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

Jerry 通过在文件开头添加单行注释来修改文件。

[jerry@CentOS src]$ head -2 string_operations.c
/* This line be removed by git reset operation */
#include <stdio.h>

他使用 git status 命令验证了这一点。

[jerry@CentOS src]$ git status -s
M string_operations.c

Jerry将修改后的文件添加到暂存区,并使用git status命令进行验证。

[jerry@CentOS src]$ git add string_operations.c
[jerry@CentOS src]$ git status

上述命令将产生以下结果。

# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#
modified: string_operations.c
#

Git 状态显示该文件存在于暂存区域中。现在,使用 --hard 选项重置 HEAD。

[jerry@CentOS src]$ git reset --hard 577647211ed44fe2ae479427a0668a4f12ed71a1

HEAD is now at 5776472 Removed executable binary

Git 重置命令成功,这将从暂存区域恢复文件并删除对该文件所做的任何本地更改。

[jerry@CentOS src]$ git status -s

Git 状态显示该文件已从暂存区域恢复。

[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>

head 命令还显示重置操作也删除了本地更改。

Git - 标签操作

标签操作允许为存储库中的特定版本提供有意义的名称。假设汤姆和杰瑞决定标记他们的项目代码,以便他们以后可以轻松访问它。

创建标签

让我们使用git tag命令标记当前的 HEAD。Tom 使用 -a 选项提供标签名称,并使用 -m 选项提供标签消息。

tom@CentOS project]$ pwd
/home/tom/top_repo/project

[tom@CentOS project]$ git tag -a 'Release_1_0' -m 'Tagged basic string operation code' HEAD

如果要标记特定提交,请使用适当的 COMMIT ID 而不是 HEAD 指针。Tom 使用以下命令将标签推送到远程存储库。

[tom@CentOS project]$ git push origin tag Release_1_0

上述命令将产生以下结果 -

Counting objects: 1, done.
Writing objects: 100% (1/1), 183 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
* [new tag]
Release_1_0 −> Release_1_0

查看标签

汤姆创建了标签。现在,Jerry 可以使用带有 –l 选项的 Git tag 命令来查看所有可用标签。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git pull
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From git.server.com:project
* [new tag]
Release_1_0 −> Release_1_0
Current branch master is up to date.

[jerry@CentOS src]$ git tag -l
Release_1_0

Jerry 使用 Git show 命令后跟其标签名称来查看有关标签的更多详细信息。

[jerry@CentOS src]$ git show Release_1_0

上述命令将产生以下结果 -

tag Release_1_0
Tagger: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 13:45:54 2013 +0530

Tagged basic string operation code


commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

diff --git a/src/string_operations b/src/string_operations
deleted file mode 100755
index 654004b..0000000
Binary files a/src/string_operations and /dev/null differ

删除标签

Tom 使用以下命令从本地和远程存储库中删除标签。

[tom@CentOS project]$ git tag
Release_1_0

[tom@CentOS project]$ git tag -d Release_1_0
Deleted tag 'Release_1_0' (was 0f81ff4)
# Remove tag from remote repository.

[tom@CentOS project]$ git push origin :Release_1_0
To gituser@git.server.com:project.git
- [deleted]
Release_1_0

Git - 补丁操作

Patch 是一个文本文件,其内容与 Git diff 类似,但除了代码之外,它还包含有关提交的元数据;例如,提交 ID、日期、提交消息等。我们可以根据提交创建补丁,其他人可以将它们应用到他们的存储库。

Jerry 为他的项目实现了 strcat 函数。Jerry 可以创建他的代码的路径并将其发送给 Tom。然后,他可以将收到的补丁应用到他的代码中。

Jerry 使用 Git format-patch命令为最新提交创建补丁。如果要为特定提交创建补丁,请使用COMMIT_ID和 format-patch 命令。

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c
?? string_operations

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m "Added my_strcat function"

[master b4c7f09] Added my_strcat function
1 files changed, 13 insertions(+), 0 deletions(-)

[jerry@CentOS src]$ git format-patch -1
0001-Added-my_strcat-function.patch

上面的命令在当前工作目录中创建.patch文件。Tom 可以使用此补丁来修改他的文件。Git 提供了两个命令来应用补丁,分别是git amgit applygit apply修改本地文件而不创建提交,而git am修改文件并创建提交。

要应用补丁并创建提交,请使用以下命令 -

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ git diff

[tom@CentOS src]$ git status –s

[tom@CentOS src]$ git apply 0001-Added-my_strcat-function.patch

[tom@CentOS src]$ git status -s
M string_operations.c
?? 0001-Added-my_strcat-function.patch

补丁已成功应用,现在我们可以使用git diff命令查看修改内容。

[tom@CentOS src]$ git diff

上述命令将产生以下结果 -

diff --git a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,5 +1,16 @@
#include <stdio.h>
+char *my_strcat(char *t, char *s)
diff --git a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,5 +1,16 @@
#include <stdio.h>
+char *my_strcat(char *t, char *s)
+
{
   +
   char *p = t;
   +
   +
   +
   while (*p)
   ++p;
   +
   while (*p++ = *s++)
   + ;
   + return t;
   +
}
+
size_t my_strlen(const char *s)
{
   const char *p = s;
   @@ -23,6 +34,7 @@ int main(void)
   {

Git - 管理分支

分支运营允许创建另一条发展线。我们可以使用此操作将开发过程分为两个不同的方向。例如,我们发布了 6.0 版本的产品,我们可能希望创建一个分支,以便 7.0 功能的开发可以与 6.0 错误修复分开。

创建分支

Tom 使用 gitbranch <branch name> 命令创建一个新分支。我们可以从现有分支创建一个新分支。我们可以使用特定的提交或标签作为起点。如果未提供任何特定的提交 ID,则将以 HEAD 作为起点创建分支。

[jerry@CentOS src]$ git branch new_branch

[jerry@CentOS src]$ git branch
* master
new_branch

创建一个新分支;Tom 使用 gitbranch 命令列出可用的分支。Git 在当前签出的分支之前显示一个星号标记。

创建分支操作的图示如下所示 -

git 教程