Git 简明教程
Git - Basic Concepts
Version Control System
Version Control System (VCS) 是一款软件,用于帮助软件开发人员共同协作并维护其工作完整记录。
Version Control System (VCS) is a software that helps software developers to work together and maintain a complete history of their work.
以下列出了 VCS 的功能 −
Listed below are the functions of a VCS −
-
Allows developers to work simultaneously.
-
Does not allow overwriting each other’s changes.
-
Maintains a history of every version.
以下为 VCS 的类型 −
Following are the types of VCS −
-
Centralized version control system (CVCS).
-
Distributed/Decentralized version control system (DVCS).
在本章中,我们将仅集中讨论分布式版本控制系统,特别是 Git。Git 属于分布式版本控制系统。
In this chapter, we will concentrate only on distributed version control system and especially on Git. Git falls under distributed version control system.
Distributed Version Control System
集中式版本控制系统 (CVCS) 使用中央服务器存储所有文件,并实现团队协作。但 CVCS 的主要缺点在于它的单点故障,即中央服务器发生故障。不幸的是,如果中央服务器中断一个小时,那么在这个小时内,根本没有人可以协作。在最坏的情况下,如果中央服务器的磁盘损坏且未进行适当的备份,那么您将丢失项目的整个历史记录。此处,分布式版本控制系统 (DVCS) 发挥了作用。
Centralized version control system (CVCS) uses a central server to store all files and enables team collaboration. But the major drawback of CVCS is its single point of failure, i.e., failure of the central server. Unfortunately, if the central server goes down for an hour, then during that hour, no one can collaborate at all. And even in a worst case, if the disk of the central server gets corrupted and proper backup has not been taken, then you will lose the entire history of the project. Here, distributed version control system (DVCS) comes into picture.
DVCS 客户端不仅可以签出目录的最新快照,还完全镜像仓库。如果服务器发生故障,那么可以从任何客户端将仓库复制回服务器,以便恢复它。每次签出都是仓库的完整备份。Git 不依赖于中央服务器,这就是为什么您在离线时可以执行许多操作的原因。您可以在离线时提交更改、创建分支、查看日志并执行其他操作。您仅需要网络连接即可发布更改并获取最新更改。
DVCS clients not only check out the latest snapshot of the directory but they also fully mirror the repository. If the server goes down, then the repository from any client can be copied back to the server to restore it. Every checkout is a full backup of the repository. Git does not rely on the central server and that is why you can perform many operations when you are offline. You can commit changes, create branches, view logs, and perform other operations when you are offline. You require network connection only to publish your changes and take the latest changes.
Advantages of Git
Free and open source
Git 在 GPL 开源许可下发布。它可免费在网上获得。您无需支付一分钱即可使用 Git 来管理房地产项目。由于它是开源的,您可以下载其源代码,并根据您的要求执行更改。
Git is released under GPL’s open source license. It is available freely over the internet. You can use Git to manage property projects without paying a single penny. As it is an open source, you can download its source code and also perform changes according to your requirements.
Fast and small
由于大多数操作都将在本地执行,因此它在速度方面具有巨大的优势。Git 不依赖于中央服务器;这就是为什么无需为每个操作与远程服务器进行交互的原因。Git 的核心部分是用 C 语言编写的,这避免了与其他高级语言相关的运行时开销。尽管 Git 镜像整个仓库,但在客户端上的数据大小却很小。这说明了 Git 在客户端压缩和存储数据方面的效率。
As most of the operations are performed locally, it gives a huge benefit in terms of speed. Git does not rely on the central server; that is why, there is no need to interact with the remote server for every operation. The core part of Git is written in C, which avoids runtime overheads associated with other high-level languages. Though Git mirrors entire repository, the size of the data on the client side is small. This illustrates the efficiency of Git at compressing and storing data on the client side.
Implicit backup
当存在多个副本时,丢失数据的机会非常罕见。客户机侧上的数据镜像仓库,因此可以在发生崩溃或磁盘损坏时使用它。
The chances of losing data are very rare when there are multiple copies of it. Data present on any client side mirrors the repository, hence it can be used in the event of a crash or disk corruption.
Security
Git 使用一种称为安全散列函数 (SHA1) 的常见加密散列函数,在数据库中对对象命名和标识。每次签出时,都会对每个文件和提交进行校验和,并通过其校验和进行检索。这意味着,在不知道 Git 的情况下,无法从 Git 数据库更改文件、日期和提交消息以及任何其他数据。
Git uses a common cryptographic hash function called secure hash function (SHA1), to name and identify objects within its database. Every file and commit is check-summed and retrieved by its checksum at the time of checkout. It implies that, it is impossible to change file, date, and commit message and any other data from the Git database without knowing Git.
No need of powerful hardware
对于 CVCS,中央服务器需要足够强大,才能为整个团队提供请求。对于较小的团队而言,这并不是问题,但随着团队规模的扩大,服务器的硬件限制可能会成为性能瓶颈。对于 DVCS,开发人员无需与服务器进行交互,除非他们需要推送或拉取更改。所有繁重的任务都在客户端上进行,因此服务器硬件确实可以非常简单。
In case of CVCS, the central server needs to be powerful enough to serve requests of the entire team. For smaller teams, it is not an issue, but as the team size grows, the hardware limitations of the server can be a performance bottleneck. In case of DVCS, developers don’t interact with the server unless they need to push or pull changes. All the heavy lifting happens on the client side, so the server hardware can be very simple indeed.
Easier branching
CVCS 使用廉价复制机制,如果我们创建一个新分支,它将所有代码复制到新分支,因此非常耗时且效率低下。此外,在 CVCS 中删除和合并分支很复杂且耗时。但使用 Git 进行分支管理非常简单。创建、删除和合并分支只需几秒钟即可完成。
CVCS uses cheap copy mechanism, If we create a new branch, it will copy all the codes to the new branch, so it is time-consuming and not efficient. Also, deletion and merging of branches in CVCS is complicated and time-consuming. But branch management with Git is very simple. It takes only a few seconds to create, delete, and merge branches.
DVCS Terminologies
Local Repository
每个 VCS 工具都提供一个私有工作区作为工作副本。开发人员在其私有工作区中进行更改,而在提交后,这些更改将成为仓库的一部分。Git 将其更进一步,为他们提供了整个仓库的私有副本。用户可以使用此仓库执行许多操作,例如添加文件、移除文件、重命名文件、移动文件、提交更改等许多操作。
Every VCS tool provides a private workplace as a working copy. Developers make changes in their private workplace and after commit, these changes become a part of the repository. Git takes it one step further by providing them a private copy of the whole repository. Users can perform many operations with this repository such as add file, remove file, rename file, move file, commit changes, and many more.
Working Directory and Staging Area or Index
工作目录是签出文件的位置。在其他 CVCS 中,开发人员通常进行修改并直接提交其更改到仓库。但是 Git 使用了一种不同的策略。Git 不会跟踪每个修改过的文件。每当您执行提交操作时,Git 都会查找暂存区中存在的文件。只有暂存区中存在的文件才会提交,而并非所有修改过的文件。
The working directory is the place where files are checked out. In other CVCS, developers generally make modifications and commit their changes directly to the repository. But Git uses a different strategy. Git doesn’t track each and every modified file. Whenever you do commit an operation, Git looks for the files present in the staging area. Only those files present in the staging area are considered for commit and not all the modified files.
让我们看看 Git 的基本工作流。
Let us see the basic workflow of Git.
Step 1 − 你修改了工作目录中的一个文件。
Step 1 − You modify a file from the working directory.
Step 2 − 你将这些文件添加到暂存区。
Step 2 − You add these files to the staging area.
Step 3 − 你执行提交操作,该操作将文件从暂存区移动。在执行推送操作后,它会将这些更改永久地存储到 Git 存储库中。
Step 3 − You perform commit operation that moves the files from the staging area. After push operation, it stores the changes permanently to the Git repository.
假设你修改了两个文件,即“sort.c”和“search.c”,并且你希望对每个操作进行两次不同的提交。你可以将一个文件添加到暂存区并进行提交。在第一次提交后,对另一个文件重复相同的过程。
Suppose you modified two files, namely “sort.c” and “search.c” and you want two different commits for each operation. You can add one file in the staging area and do commit. After the first commit, repeat the same procedure for another file.
# 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”
Blobs
Blob 表示 二进制 大 对象。文件的每个版本都由 blob 表示。blob 保存着文件数据,但不包含任何关于该文件元数据。它是一个二进制文件,在 Git 数据库中,它被命名为该文件 SHA1 哈希值。在 Git 中,文件并非通过名称来寻址。每种文件都是根据其内容进行寻址的。
Blob stands for *B*inary *L*arge *Ob*ject. Each version of a file is represented by blob. A blob holds the file data but doesn’t contain any metadata about the file. It is a binary file, and in Git database, it is named as SHA1 hash of that file. In Git, files are not addressed by names. Everything is content-addressed.
Trees
Tree 是一个对象,表示一个目录。它保存着 blob 和其他子目录。tree 是一个二进制文件,它存储着对 blob 和 tree 的引用,它们也被命名为树对象的 SHA1 哈希值。
Tree is an object, which represents a directory. It holds blobs as well as other sub-directories. A tree is a binary file that stores references to blobs and trees which are also named as SHA1 hash of the tree object.
Commits
Commit 存储着存储库的当前状态。commit 也被 SHA1 哈希值命名。你可以将 commit 对象视作一个链表的节点。每个 commit 对象都有一个父级 commit 对象指针。从给定的 commit 开始,你可以通过查看父级指针来追溯历史提交。如果一个 commit 有多个父级 commit,那么该特定 commit 是通过合并两个分支创建的。
Commit holds the current state of the repository. A commit is also named by SHA1 hash. You can consider a commit object as a node of the linked list. Every commit object has a pointer to the parent commit object. From a given commit, you can traverse back by looking at the parent pointer to view the history of the commit. If a commit has multiple parent commits, then that particular commit has been created by merging two branches.
Branches
Branch 用来创建另一个开发线路。默认情况下,Git 有一个 master 分支,它与 Subversion 的 trunk 相同。一般来说,一个分支被创建来开发一个新功能。一旦该功能完成,它就会被合并回 master 分支,然后我们删除这个分支。每个分支都通过 HEAD 引用,该引用指向分支中的最新 commit。每当你进行一次 commit,HEAD 就会被更新为最新 commit。
Branches are used to create another line of development. By default, Git has a master branch, which is same as trunk in Subversion. Usually, a branch is created to work on a new feature. Once the feature is completed, it is merged back with the master branch and we delete the branch. Every branch is referenced by HEAD, which points to the latest commit in the branch. Whenever you make a commit, HEAD is updated with the latest commit.
Tags
Tag 使用一个有意义的名称为存储库中的一个特定版本命名。Tag 与分支非常相似,但不同之处在于 tag 是不可变的。这意味着,tag 是一个分支,没有人打算对其进行修改。一旦为特定 commit 创建了一个 tag,即使你创建了一个新的 commit,它也不会被更新。一般来说,开发人员会在产品发布时创建 tag。
Tag assigns a meaningful name with a specific version in the repository. Tags are very similar to branches, but the difference is that tags are immutable. It means, tag is a branch, which nobody intends to modify. Once a tag is created for a particular commit, even if you create a new commit, it will not be updated. Usually, developers create tags for product releases.
Clone
Clone 操作创建存储库的实例。Clone 操作不仅会检出工作副本,还会镜像整个存储库。用户可以使用 此本地存储库执行许多操作。进行网络交互的唯一时间是存储库实例正在同步的时候。
Clone operation creates the instance of the repository. Clone operation not only checks out the working copy, but it also mirrors the complete repository. Users can perform many operations with this local repository. The only time networking gets involved is when the repository instances are being synchronized.
Pull
Pull 操作将更改从一个远程存储库实例复制到一个本地存储库实例。pull 操作用于在两个存储库实例之间执行同步。这与 Subversion 中的更新操作相同。
Pull operation copies the changes from a remote repository instance to a local one. The pull operation is used for synchronization between two repository instances. This is same as the update operation in Subversion.
Push
Push 操作将更改从一个本地存储库实例复制到一个远程存储库实例。这用于将更改永久地存储到 Git 存储库中。这与 Subversion 中的 commit 操作相同。
Push operation copies changes from a local repository instance to a remote one. This is used to store the changes permanently into the Git repository. This is same as the commit operation in Subversion.
HEAD
HEAD 是一个指针,它总是指向分支中的最新 commit。每当你进行一次 commit,HEAD 就会被更新为最新 commit。分支的头部存储在 .git/refs/heads/ 目录中。
HEAD is a pointer, which always points to the latest commit in the branch. Whenever you make a commit, HEAD is updated with the latest commit. The heads of the branches are stored in .git/refs/heads/ directory.
[CentOS]$ ls -1 .git/refs/heads/
master
[CentOS]$ cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49
Revision
Revision 表示源代码的版本。Git 中的 Revision 由 commit 表示。这些 commit 通过 SHA1 安全哈希值来识别。
Revision represents the version of the source code. Revisions in Git are represented by commits. These commits are identified by SHA1 secure hashes.
URL
URL 表示 Git 存储库的位置。Git URL 存储在配置文件中。
URL represents the location of the Git repository. Git URL is stored in config file.
[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 - Environment Setup
在使用 Git 之前,您必须安装并执行一些基本配置更改。以下是有关在 Ubuntu 和 Centos Linux 上安装 Git 客户端的步骤。
Before you can use Git, you have to install and do some basic configuration changes. Below are the steps to install Git client on Ubuntu and Centos Linux.
Installation of Git Client
如果您使用 Debian 基础 GNU/Linux 发行版,则 apt-get 命令将完成必要的操作。
If you are using Debian base GNU/Linux distribution, then apt-get command will do the needful.
[ubuntu ~]$ sudo apt-get install git-core
[sudo] password for ubuntu:
[ubuntu ~]$ git --version
git version 1.8.1.2
如果您使用基于 RPM 的 GNU/Linux 发行版,请按照给定的使用 yum 命令。
And if you are using RPM based GNU/Linux distribution, then use yum command as given.
[CentOS ~]$
su -
Password:
[CentOS ~]# yum -y install git-core
[CentOS ~]# git --version
git version 1.7.1
Customize Git Environment
Git 提供了 git config 工具,允许您设置配置变量。Git 将所有全局配置存储在 .gitconfig 文件中,该文件位于您的主目录中。要将这些配置值设置为全局,请添加 --global 选项,如果您省略 --global 选项,则您的配置特定于当前 Git 存储库。
Git provides the git config tool, which allows you to set configuration variables. Git stores all global configurations in .gitconfig file, which is located in your home directory. To set these configuration values as global, add the --global option, and if you omit --global option, then your configurations are specific for the current Git repository.
您还可以设置系统范围内的配置。Git 将这些值存储在 /etc/gitconfig 文件中,其中包含系统上每个用户和存储库的配置。要设置这些值,您必须拥有 root 权限并使用 --system 选项。
You can also set up system wide configuration. Git stores these values in the /etc/gitconfig file, which contains the configuration for every user and repository on the system. To set these values, you must have the root rights and use the --system option.
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
Setting username
Git 在每次提交时都会使用这些信息。
This information is used by Git for each commit.
[jerry@CentOS project]$ git config --global user.name "Jerry Mouse"
Setting email id
Git 在每次提交时都会使用这些信息。
This information is used by Git for each commit.
[jerry@CentOS project]$ git config --global user.email "jerry@tutorialspoint.com"
Avoid merge commits for pulling
您从远程存储库拉取最新的更改,如果这些更改是不同的,那么默认情况下 Git 会创建合并提交。我们可以通过以下设置避免这种情况。
You pull the latest changes from a remote repository, and if these changes are divergent, then by default Git creates merge commits. We can avoid this via following settings.
jerry@CentOS project]$ git config --global branch.autosetuprebase always
Color highlighting
以下命令为控制台中的 Git 启用颜色高亮显示。
The following commands enable color highlighting for Git in the console.
[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
Setting default editor
默认情况下,Git 使用从 VISUAL 或 EDITOR 环境变量中获取的系统默认编辑器。我们可以使用 git config 配置不同的编辑器。
By default, Git uses the system default editor, which is taken from the VISUAL or EDITOR environment variable. We can configure a different one by using git config.
[jerry@CentOS project]$ git config --global core.editor vim
Setting default merge tool
Git 不提供用于将冲突更改集成到您的工作树中的默认合并工具。我们可以通过启用以下设置来设置默认合并工具。
Git does not provide a default merge tool for integrating conflicting changes into your working tree. We can set default merge tool by enabling following settings.
[jerry@CentOS project]$ git config --global merge.tool vimdiff
Listing Git settings
若要验证本地存储库的 Git 设置,请按照给出下文所示使用 git config –list 命令。
To verify your Git settings of the local repository, use git config –list command as given below.
[jerry@CentOS ~]$ git config --list
上述命令将产生以下结果。
The above command will produce the following result.
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 - Life Cycle
在本章中,我们将讨论 Git 的生命周期。在后面的章节中,我们将介绍每个操作的 Git 命令。
In this chapter, we will discuss the life cycle of Git. In later chapters, we will cover the Git commands for each operation.
一般工作流程如下 −
General workflow is as follows −
-
You clone the Git repository as a working copy.
-
You modify the working copy by adding/editing files.
-
If necessary, you also update the working copy by taking other developer’s changes.
-
You review the changes before commit.
-
You commit changes. If everything is fine, then you push the changes to the repository.
-
After committing, if you realize something is wrong, then you correct the last commit and push the changes to the repository.
以下是工作流程的图片表示。
Shown below is the pictorial representation of the work-flow.
Git - Create Operation
在本教程中,我们将看到如何创建远程 Git 存储库;从现在起,我们将称之为 Git 服务器。我们需要 Git 服务器才能实现团队协作。
In this chapter, we will see how to create a remote Git repository; from now on, we will refer to it as Git Server. We need a Git server to allow team collaboration.
Create New User
# 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
上述命令将产生以下结果。
The above command will produce the following result.
Changing password for user gituser.
New password:
Retype new password:
passwd: all authentication token updated successfully.
Create a Bare Repository
让我们使用 init 命令,后面跟 --bare 选项,来初始化一个新存储库。它初始化存储库,而没有工作目录。按照惯例,裸存储库必须命名为 .git 。
Let us initialize a new repository by using init command followed by --bare option. It initializes the repository without a working directory. By convention, the bare repository must be named as .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
Generate Public/Private RSA Key Pair
让我们逐步完成配置 Git 服务器的过程, ssh-keygen 实用程序生成公钥/私钥 RSA 密钥对,我们将使用该密钥对进行用户身份验证。
Let us walk through the process of configuring a Git server, ssh-keygen utility generates public/private RSA key pair, that we will use for user authentication.
打开终端,输入以下命令,并在每个输入后面按 Enter。成功完成后,它会在主目录中创建一个 .ssh 目录。
Open a terminal and enter the following command and just press enter for each input. After successful completion, it will create a .ssh directory inside the home directory.
tom@CentOS ~]$ pwd
/home/tom
[tom@CentOS ~]$ ssh-keygen
上述命令将产生以下结果。
The above command will produce the following result.
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)。
ssh-keygen has generated two keys, first one is private (i.e., id_rsa) and the second one is public (i.e., id_rsa.pub).
Note: 绝不要与其他人共享您的私人密钥。
Note: Never share your PRIVATE KEY with others.
Adding Keys to authorized_keys
假设有两位开发人员正在处理某个项目,他们分别是 Tom 和 Jerry。两个用户都生成了公钥。让我们了解如何使用这些密钥进行验证。
Suppose there are two developers working on a project, namely Tom and Jerry. Both users have generated public keys. Let us see how to use these keys for authentication.
Tom 使用 ssh-copy-id 命令将他的公钥添加到服务器,如下所示:
Tom added his public key to the server by using ssh-copy-id command as given below −
[tom@CentOS ~]$ pwd
/home/tom
[tom@CentOS ~]$ ssh-copy-id -i ~/.ssh/id_rsa.pub gituser@git.server.com
上述命令将产生以下结果。
The above command will produce the following result.
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 命令将他的公钥添加到服务器。
Similarly, Jerry added his public key to the server by using ssh-copy-id command.
[jerry@CentOS ~]$ pwd
/home/jerry
[jerry@CentOS ~]$ ssh-copy-id -i ~/.ssh/id_rsa gituser@git.server.com
上述命令将产生以下结果。
The above command will produce the following result.
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.
Push Changes to the Repository
我们在服务器上创建了一个裸存储库,并允许两位用户访问。从现在起,Tom 和 Jerry 可以通过将其作为远程存储库添加的方式向存储库推送他们的更改。
We have created a bare repository on the server and allowed access for two users. From now on, Tom and Jerry can push their changes to the repository by adding it as a remote.
Git init 命令创建一个 .git 目录,以便每次从 .git/config 文件读取配置时存储有关存储库的元数据。
Git init command creates .git directory to store metadata about the repository every time it reads the configuration from the .git/config file.
Tom 创建一个新目录,添加 README 文件,并将他的更改提交作为初始提交。提交后,他通过运行 git log 命令验证提交消息。
Tom creates a new directory, adds README file, and commits his change as initial commit. After commit, he verifies the commit message by running the git log command.
[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'
上述命令将产生以下结果。
The above command will produce the following result.
[master (root-commit) 19ae206] Initial commit
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 README
Tom 通过执行 git log 命令检查日志消息。
Tom checks the log message by executing the git log command.
[tom@CentOS tom_repo]$ git log
上述命令将产生以下结果。
The above command will produce the following result.
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
Tom 将他的更改提交到本地存储库。现在,是时候将更改推送到远程存储库了。但在那之前,我们必须将存储库添加为远程存储库,这是一次性操作。在此之后,他可以安全地将更改推送到远程存储库。
Tom committed his changes to the local repository. Now, it’s time to push the changes to the remote repository. But before that, we have to add the repository as a remote, this is a one-time operation. After this, he can safely push the changes to the remote repository.
Note - 默认情况下,Git 只推送至匹配的分支:对于本地侧存在的每个分支,如果那里已经存在具有相同名称的分支,则会更新远程侧。在我们的教程中,每次我们向 origin master 分支推送更改时,请根据您的要求使用适当的分支名称。
Note − By default, Git pushes only to matching branches: For every branch that exists on the local side, the remote side is updated if a branch with the same name already exists there. In our tutorials, every time we push changes to the origin master branch, use appropriate branch name according to your requirement.
[tom@CentOS tom_repo]$ git remote add origin gituser@git.server.com:project.git
[tom@CentOS tom_repo]$ git push origin master
上述命令将产生以下结果。
The above command will produce the following result.
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
现在,更改已成功提交到远程存储库。
Now, the changes are successfully committed to the remote repository.
Git - Clone Operation
我们在 Git 服务器上有一个裸存储库,Tom 也推送了他的第一个版本。现在,Jerry 可以查看他的更改。Clone 操作创建远程存储库的实例。
We have a bare repository on the Git server and Tom also pushed his first version. Now, Jerry can view his changes. The Clone operation creates an instance of the remote repository.
Jerry 在自己的主目录中创建一个新目录并执行 clone 操作。
Jerry creates a new directory in his home directory and performs the clone operation.
[jerry@CentOS ~]$ mkdir jerry_repo
[jerry@CentOS ~]$ cd jerry_repo/
[jerry@CentOS jerry_repo]$ git clone gituser@git.server.com:project.git
上述命令将产生以下结果。
The above command will produce the following result.
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 changes the directory to new local repository and lists its directory contents.
[jerry@CentOS jerry_repo]$ cd project/
[jerry@CentOS jerry_repo]$ ls
README
Git - Perform Changes
Jerry 克隆了存储库并决定实现基本字符串操作。因此,他创建了 string.c 文件。添加内容后,string.c 将如下所示 −
Jerry clones the repository and decides to implement basic string operations. So he creates string.c file. After adding the contents, string.c will look like as follows −
#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;
}
他编译并测试了代码,一切都运行良好。现在,他可以安全地将这些更改添加到仓库中。
He compiled and tested his code and everything is working fine. Now, he can safely add these changes to the repository.
Git add 操作将文件添加到暂存区。
Git add operation adds file to the staging area.
[jerry@CentOS project]$ git status -s
?? string
?? string.c
[jerry@CentOS project]$ git add string.c
Git在文件名之前显示一个问号。显然,这些文件不属于 Git,这就是为什么 Git 不知道如何处理这些文件。因此,Git 在文件名之前显示一个问号。
Git is showing a question mark before file names. Obviously, these files are not a part of Git, and that is why Git does not know what to do with these files. That is why, Git is showing a question mark before file names.
Jerry 已将文件添加到暂存区,git status 命令将显示暂存区中的文件。
Jerry has added the file to the stash area, git status command will show files present in the staging area.
[jerry@CentOS project]$ git status -s
A string.c
?? string
为了提交这些更改,他使用了 git commit 命令,后跟 -m 选项。如果我们省略 -m 选项。Git 将打开一个文本编辑器,我们可以在其中编写多行提交消息。
To commit the changes, he used the git commit command followed by –m option. If we omit –m option. Git will open a text editor where we can write multiline commit message.
[jerry@CentOS project]$ git commit -m 'Implemented my_strlen function'
以上命令将生成以下结果 −
The above command will produce the following result −
[master cbe1249] Implemented my_strlen function
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c
提交后,为了查看日志详情,他运行 git log 命令。它将显示所有提交的信息,包括提交 ID、提交作者、提交日期和提交的 SHA-1 哈希。
After commit to view log details, he runs the git log command. It will display the information of all the commits with their commit ID, commit author, commit date and SHA-1 hash of commit.
[jerry@CentOS project]$ git log
以上命令将生成以下结果 −
The above command will produce the following result −
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 - Review Changes
在查看提交详细信息后,杰瑞意识到字符串长度不能为负,因此他决定更改 my_strlen 函数的返回类型。
After viewing the commit details, Jerry realizes that the string length cannot be negative, that’s why he decides to change the return type of my_strlen function.
杰瑞使用 git log 命令查看日志详细信息。
Jerry uses the git log command to view log details.
[jerry@CentOS project]$ git log
上述命令将产生以下结果。
The above command will produce the following result.
commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530
Implemented my_strlen function
杰瑞使用 git show 命令查看提交详细信息。git show 命令采用 SHA-1 提交 ID 作为参数。
Jerry uses the git show command to view the commit details. The git show command takes SHA-1 commit ID as a parameter.
[jerry@CentOS project]$ git show cbe1249b140dad24b2c35b15cc7e26a6f02d2277
以上命令将生成以下结果 −
The above command will produce the following result −
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 命令审查自己的更改。
He changes the return type of the function from int to size_t. After testing the code, he reviews his changes by running the git diff command.
[jerry@CentOS project]$ git diff
以上命令将生成以下结果 −
The above command will produce the following result −
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 diff shows '+' sign before lines, which are newly added and '−' for deleted lines.
Git - Commit Changes
Jerry 已经提交了更改,并且想要纠正他最近的提交。在这种情况下, git amend 操作将有所帮助。amend 操作会更改最后的提交,包括您的提交信息;它会创建一个新的提交 ID。
Jerry has already committed the changes and he wants to correct his last commit. In this case, git amend operation will help. The amend operation changes the last commit including your commit message; it creates a new commit ID.
在 amend 操作之前,他检查提交日志。
Before amend operation, he checks the commit log.
[jerry@CentOS project]$ git log
上述命令将产生以下结果。
The above command will produce the following result.
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 commits the new changes with — amend operation and views the commit log.
[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 的新提交信息 −
Now, git log will show new commit message with new commit ID −
[jerry@CentOS project]$ git log
上述命令将产生以下结果。
The above command will produce the following result.
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 - Push Operation
Jerry 使用 amend 操作修改了他的最后提交,并且他准备推送更改。推送操作将数据永久存储到 Git 存储库中。在推送操作成功后,其他开发人员可以看到 Jerry 的更改。
Jerry modified his last commit by using the amend operation and he is ready to push the changes. The Push operation stores data permanently to the Git repository. After a successful push operation, other developers can see Jerry’s changes.
他执行 git log 命令以查看提交详细信息。
He executes the git log command to view the commit details.
[jerry@CentOS project]$ git log
上述命令将生成以下结果:
The above command will produce the following result:
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 命令来查看他的更改。
Before push operation, he wants to review his changes, so he uses the git show command to review his changes.
[jerry@CentOS project]$ git show d1e19d316224cddc437e3ed34ec3c931ad803958
上述命令将生成以下结果:
The above command will produce the following result:
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 对他的更改很满意,并且他准备推送他的更改。
Jerry is happy with his changes and he is ready to push his changes.
[jerry@CentOS project]$ git push origin master
上述命令将生成以下结果:
The above command will produce the following result:
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 的更改已被成功推送到存储库;现在其他开发人员可以通过执行克隆或更新操作查看他的更改。
Jerry’s changes have been successfully pushed to the repository; now other developers can view his changes by performing clone or update operation.
Git - Update Operation
Modify Existing Function
Tom 执行克隆操作并找到了一个新文件 string.c。他想了解是谁将此文件添加到仓库的以及出于什么目的,因此他执行了 git log 命令。
Tom performs the clone operation and finds a new file string.c. He wants to know who added this file to the repository and for what purpose, so, he executes the git log command.
[tom@CentOS ~]$ git clone gituser@git.server.com:project.git
以上命令将生成以下结果 −
The above command will produce the following result −
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 命令。
The Clone operation will create a new directory inside the current working directory. He changes the directory to newly created directory and executes the git log command.
[tom@CentOS ~]$ cd project/
[tom@CentOS project]$ git log
以上命令将生成以下结果 −
The above command will produce the following result −
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 添加的,以实现基本字符串操作。他对 Jerry 的代码感到好奇。因此,他在文本编辑器中打开了 string.c,并立即发现了错误。在 my_strlen 函数中,Jerry 没有使用常量指针。所以,他决定修改 Jerry 的代码。修改后,代码如下 −
After observing the log, he realizes that the file string.c was added by Jerry to implement basic string operations. He is curious about Jerry’s code. So he opens string.c in text editor and immediately finds a bug. In my_strlen function, Jerry is not using a constant pointer. So, he decides to modify Jerry’s code. After modification, the code looks as follows −
[tom@CentOS project]$ git diff
以上命令将生成以下结果 −
The above command will produce the following result −
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;
}
在测试后,他提交了他的更改。
After testing, he commits his change.
[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
以上命令将生成以下结果 −
The above command will produce the following result −
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 uses git push command to push his changes.
[tom@CentOS project]$ git push origin master
以上命令将生成以下结果 −
The above command will produce the following result −
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
Add New Function
与此同时,Jerry 决定实现 string compare 功能。因此,他修改了 string.c。修改后,该文件如下所示 −
Meanwhile, Jerry decides to implement string compare functionality. So he modifies string.c. After modification, the file looks as follows −
[jerry@CentOS project]$ git diff
以上命令将生成以下结果 −
The above command will produce the following result −
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;
}
}
经过测试,他准备推送自己的变更。
After testing, he is ready to push his change.
[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(-)
在推送操作之前,他通过查看日志消息验证提交。
Before push operation, he verifies commit by viewing log messages.
[jerry@CentOS project]$ git log
以上命令将生成以下结果 −
The above command will produce the following result −
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 对更改感到满意,他想推送他的更改。
Jerry is happy with the changes and he wants to push his changes.
[jerry@CentOS project]$ git push origin master
以上命令将生成以下结果 −
The above command will produce the following result −
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 必须首先更新本地仓库,然后才能推送自己的更改。
But Git is not allowing Jerry to push his changes. Because Git identified that remote repository and Jerry’s local repository are not in sync. Because of this, he can lose the history of the project. To avoid this mess, Git failed this operation. Now, Jerry has to first update the local repository and only thereafter, he can push his own changes.
Fetch Latest Changes
Jerry 执行 git pull 命令将他的本地仓库与远程仓库同步。
Jerry executes the git pull command to synchronize his local repository with the remote one.
[jerry@CentOS project]$ git pull
以上命令将生成以下结果 −
The above command will produce the following result −
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
在 pull 操作之后,Jerry 检查日志消息并查找 Tom 的提交的详细信息,提交 ID 为 cea2c000f53ba99508c5959e3e12fff493ba6f69
After pull operation, Jerry checks the log messages and finds the details of Tom’s commit with commit ID cea2c000f53ba99508c5959e3e12fff493ba6f69
[jerry@CentOS project]$ git log
以上命令将生成以下结果 −
The above command will produce the following result −
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 的本地仓库已与远程仓库完全同步。因此,他可以安全地推送自己的更改。
Now, Jerry’s local repository is fully synchronized with the remote repository. So he can safely push his changes.
[jerry@CentOS project]$ git push origin master
以上命令将生成以下结果 −
The above command will produce the following result −
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 - Stash Operation
假设你正在为你的产品实现一种新功能。你的代码正在进行中,突然收到客户升级。由于这一点,你不得不搁置你的新功能工作几个小时。你无法提交你的部分代码,也不能抛弃你的更改。所以,你需要一些临时空间,在那里你可以存储你的部分更改并在以后提交它们。
Suppose you are implementing a new feature for your product. Your code is in progress and suddenly a customer escalation comes. Because of this, you have to keep aside your new feature work for a few hours. You cannot commit your partial code and also cannot throw away your changes. So you need some temporary space, where you can store your partial changes and later on commit it.
在 Git 中,存储操作需要你的已修改的跟踪文件、阶段更改,并将它们保存到一个未完成的更改堆栈中,你可以在任何时候重新应用这些更改。
In Git, the stash operation takes your modified tracked files, stages changes, and saves them on a stack of unfinished changes that you can reapply at any time.
[jerry@CentOS project]$ git status -s
M string.c
?? string
现在,你想切换分支进行客户升级,但你不想提交你尚未完成的工作,因此你将存储这些更改。要将一个新存储推送到你的堆栈中,请运行 git stash 命令。
Now, you want to switch branches for customer escalation, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run the git stash command.
[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 命令对其进行验证。
Now, your working directory is clean and all the changes are saved on a stack. Let us verify it with the git status command.
[jerry@CentOS project]$ git status -s
?? string
现在,你可以安全切换分支并在其他地方工作。我们可以使用 git stash list 命令查看存储的更改的列表。
Now you can safely switch the branch and work elsewhere. We can view a list of stashed changes by using the git stash list command.
[jerry@CentOS project]$ git stash list
stash@{0}: WIP on master: e86f062 Added my_strcpy function
假设你已解决了客户升级,并且你回到新功能正在寻找你一半完成的代码,只需执行 git stash pop 命令,即可从堆栈中删除更改并将它们放置在当前工作目录中。
Suppose you have resolved the customer escalation and you are back on your new feature looking for your half-done code, just execute the git stash pop command, to remove the changes from the stack and place them in the current working directory.
[jerry@CentOS project]$ git status -s
?? string
[jerry@CentOS project]$ git stash pop
上述命令将生成以下结果:
The above command will produce the following result:
# 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 - Move Operation
顾名思义,移动操作会将目录或文件从一个位置移动到另一个位置。汤姆决定将源代码移动到 src 目录。修改后的目录结构将如下所示:
As the name suggests, the move operation moves a directory or a file from one location to another. Tom decides to move the source code into src directory. The modified directory structure will appear as follows −
[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
要使这些更改成为永久更改,我们必须将修改的目录结构推送到远程仓库中,以便其他开发人员可以查看。
To make these changes permanent, we have to push the modified directory structure to the remote repository so that other developers can see this.
[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 的本地仓库中,在拉取操作之前,将显示旧的目录结构。
In Jerry’s local repository, before the pull operation, it will show the old directory structure.
[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project
[jerry@CentOS project]$ ls
README string string.c
但在拉取操作之后,目录结构将更新。现在,Jerry 可以看到 src 目录以及该目录中存在的文件。
But after the pull operation, the directory structure will get updated. Now, Jerry can see the src directory and the file present inside that directory.
[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 - Rename Operation
到目前为止,Tom 和 Jerry 都在使用手动命令编译他们的项目。现在,Jerry 决定为他们的项目创建 Makefile,并且还要为文件“string.c”提供一个恰当的名称。
Till now, both Tom and Jerry were using manual commands to compile their project. Now, Jerry decides to create Makefile for their project and also give a proper name to the file “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 以指示该文件已重命名。
Git is showing R before file name to indicate that the file has been renamed.
对于提交操作,Jerry 使用 -a 标志,这使得 git 提交自动检测已修改的文件。
For commit operation, Jerry used -a flag, that makes git commit automatically detect the modified files.
[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%)
在提交之后,他将更改推送到仓库。
After commit, he pushes his changes to the repository.
[jerry@CentOS src]$ git push origin master
以上命令将生成以下结果 −
The above command will produce the following result −
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
现在,其他开发人员可以通过更新其本地存储库来查看这些修改。
Now, other developers can view these modifications by updating their local repository.
Git - Delete Operation
Tom 更新他的本地仓库,并在 src 目录中找到已编译的二进制文件。在查看提交消息后,他意识到此编译的二进制文件是由 Jerry 添加的。
Tom updates his local repository and finds the compiled binary in the src directory. After viewing the commit message, he realizes that the compiled binary was added by 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 命令。
VCS is used to store the source code only and not executable binaries. So, Tom decides to remove this file from the repository. For further operation, he uses the git rm command.
[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
在提交之后,他将更改推送到仓库。
After commit, he pushes his changes to the repository.
[tom@CentOS src]$ git push origin master
上述命令将产生以下结果。
The above command will produce the following result.
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 - Fix Mistakes
人非圣贤,孰能无过。因此,每个 VCS 都提供了在一定范围内修复错误的功能。Git 提供了一个功能,我们可以使用该功能撤销对本地存储库所做的修改。
To err is human. So every VCS provides a feature to fix mistakes until a certain point. Git provides a feature that we can use to undo the modifications that have been made to the local repository.
假设用户错误地对他的本地存储库进行了一些更改,然后想要撤销这些更改。在这种情况下, revert 操作将发挥重要作用。
Suppose the user accidentally does some changes to his local repository and then wants to undo these changes. In such cases, the revert operation plays an important role.
Revert Uncommitted Changes
让我们假设 Jerry 错误地修改了他本地存储库中的一个文件。但是,他想要撤销他的修改。为了处理这种情况,我们可以使用 git checkout 命令。我们可以使用这个命令来还原文件的内容。
Let us suppose Jerry accidentally modifies a file from his local repository. But he wants to undo his modification. To handle this situation, we can use the git checkout command. We can use this command to revert the contents of a file.
[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 从本地存储库中删除了一个文件,并且我们想要恢复这个文件。我们可以使用相同的命令来实现这一点。
Further, we can use the git checkout command to obtain a deleted file from the local repository. Let us suppose Tom deletes a file from the local repository and we want this file back. We can achieve this by using the same command.
[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 。这表示该文件已从本地存储库中删除。
Git is showing the letter D before the filename. This indicates that the file has been deleted from the local repository.
[tom@CentOS src]$ git checkout string_operations.c
[tom@CentOS src]$ ls -1
Makefile
string_operations.c
[tom@CentOS src]$ git status -s
Note − 我们可以在提交前执行所有这些操作。
Note − We can perform all these operations before commit.
Remove Changes from Staging Area
我们已经看到当我们执行一个添加操作时,文件从本地仓库移动到暂存区域。如果一个用户意外地修改了一个文件并将其添加到暂存区域中,他可以使用 git checkout 命令撤销他的修改。
We have seen that when we perform an add operation, the files move from the local repository to the stating area. If a user accidently modifies a file and adds it into the staging area, he can revert his changes, by using the git checkout command.
在 Git 中,有一个 HEAD 指针始终指向最新的提交。如果你想要撤销一个来自暂存区域的修改,你可以使用 git checkout 命令,使用 checkout 命令的时候,你必须提供一个额外的参数,即 HEAD 指针。额外的提交指针参数指示 git checkout 命令重置工作树并移除暂存修改。
In Git, there is one HEAD pointer that always points to the latest commit. If you want to undo a change from the staged area, then you can use the git checkout command, but with the checkout command, you have to provide an additional parameter, i.e., the HEAD pointer. The additional commit pointer parameter instructs the git checkout command to reset the working tree and also to remove the staged changes.
假设 Tom 从他的本地仓库中修改了一个文件。如果我们查看这个文件的状态,它将会显示文件已经修改但是尚未添加到暂存区域中。
Let us suppose Tom modifies a file from his local repository. If we view the status of this file, it will show that the file was modified but not added into the staging area.
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 命令撤销它并查看撤销的文件的状态。
Git status shows that the file is present in the staging area, now revert it by using the git checkout command and view the status of the reverted file.
[tom@CentOS src]$ git checkout HEAD -- string_operations.c
[tom@CentOS src]$ git status -s
Move HEAD Pointer with Git Reset
完成了一些修改之后,你可能决定移除这些修改。Git reset 命令用于重置或撤销修改。我们可以执行三种不同类型的重置操作。
After doing few changes, you may decide to remove these changes. The Git reset command is used to reset or revert changes. We can perform three different types of reset operations.
下图展示了 Git reset 命令的图片表示。
Below diagram shows the pictorial representation of Git reset command.
Soft
每个分支都有一个 HEAD 指针,指向最新的提交。如果我们使用带有 --soft 选项的 Git reset 命令,后面跟着提交 ID,那么它仅仅会在不销毁任何东西的情况下重置 HEAD 指针。
Each branch has a HEAD pointer, which points to the latest commit. If we use Git reset command with --soft option followed by commit ID, then it will reset the HEAD pointer only without destroying anything.
.git/refs/heads/master 文件储存了 HEAD 指针的提交 ID。我们可以使用 git log -1 命令验证它。
.git/refs/heads/master file stores the commit ID of the HEAD pointer. We can verify it by using the git log -1 command.
[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1
现在,查看最新的提交 ID,它将会与上面的提交 ID 相匹配。
Now, view the latest commit ID, which will match with the above commit ID.
[jerry@CentOS project]$ git log -2
上述命令将产生以下结果。
The above command will produce the following result.
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 指针。
Let us reset the HEAD pointer.
[jerry@CentOS project]$ git reset --soft HEAD~
现在,我们简单地将 HEAD 指针回退一个位置。让我们检查 .git/refs/heads/master file 的内容。
Now, we just reset the HEAD pointer back by one position. Let us check the contents of .git/refs/heads/master file.
[jerry@CentOS project]$ cat .git/refs/heads/master
29af9d45947dc044e33d69b9141d8d2dad37cc62
文件中的提交 ID 已经改变,现在通过查看提交信息来验证它。
Commit ID from file is changed, now verify it by viewing commit messages.
jerry@CentOS project]$ git log -2
上述命令将产生以下结果。
The above command will produce the following result.
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 reset 带有 --mixed 选项会撤销那些尚未提交的来自暂存区域的修改。它仅仅会撤销来自暂存区域的修改。对文件工作副本所做的实际修改不会受到影响。默认的 Git reset 等同于 git reset — mixed。
Git reset with --mixed option reverts those changes from the staging area that have not been committed yet. It reverts the changes from the staging area only. The actual changes made to the working copy of the file are unaffected. The default Git reset is equivalent to the git reset — mixed.
hard
如果你对 Git reset 命令使用 --hard 选项,它将会清空暂存区域;它将会将 HEAD 指针重置为特定提交 ID 的最新提交,也会删除本地文件修改。
If you use --hard option with the Git reset command, it will clear the staging area; it will reset the HEAD pointer to the latest commit of the specific commit ID and delete the local file changes too.
让我们检查提交 ID。
Let us check the commit ID.
[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src
[jerry@CentOS src]$ git log -1
上述命令将产生以下结果。
The above command will produce the following result.
commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530
Removed executable binary
Jerry 通过在文件开头添加单行注释来修改了文件。
Jerry modified a file by adding single-line comment at the start of file.
[jerry@CentOS src]$ head -2 string_operations.c
/* This line be removed by git reset operation */
#include <stdio.h>
他使用 git status 命令验证了它。
He verified it by using the git status command.
[jerry@CentOS src]$ git status -s
M string_operations.c
Jerry 将修改的文件添加到暂存区域,并使用 git status 命令验证了它。
Jerry adds the modified file to the staging area and verifies it with the git status command.
[jerry@CentOS src]$ git add string_operations.c
[jerry@CentOS src]$ git status
上述命令将产生以下结果。
The above command will produce the following result.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#
modified: string_operations.c
#
Git 状态显示文件出现在暂存区域中。现在,使用重置命令——硬选项重置 HEAD。
Git status is showing that the file is present in the staging area. Now, reset HEAD with — hard option.
[jerry@CentOS src]$ git reset --hard 577647211ed44fe2ae479427a0668a4f12ed71a1
HEAD is now at 5776472 Removed executable binary
Git 重置命令成功,它将从暂存区撤消文件并删除对该文件进行的所有本地更改。
Git reset command succeeded, which will revert the file from the staging area as well as remove any local changes made to the file.
[jerry@CentOS src]$ git status -s
Git 状态显示文件已从暂存区域撤消。
Git status is showing that the file has been reverted from the staging area.
[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>
head 命令还显示了重置操作也移除了本地更改。
The head command also shows that the reset operation removed the local changes too.
Git - Tag Operation
标记操作允许为存储库中的特定版本指定有意义的名称。假设汤姆和杰瑞决定标记他们的项目代码,以便他们以后可以轻松访问它。
Tag operation allows giving meaningful names to a specific version in the repository. Suppose Tom and Jerry decide to tag their project code so that they can later access it easily.
Create Tags
让我们使用 git tag 命令标记当前 HEAD。汤姆使用 -a 选项提供标记名称,并使用 –m 选项提供标记消息。
Let us tag the current HEAD by using the git tag command. Tom provides a tag name with -a option and provides a tag message with –m option.
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 指针。汤姆使用以下命令将标记推送到远程存储库。
If you want to tag a particular commit, then use the appropriate COMMIT ID instead of the HEAD pointer. Tom uses the following command to push the tag into the remote repository.
[tom@CentOS project]$ git push origin tag Release_1_0
以上命令将生成以下结果 −
The above command will produce the following result −
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
View Tags
汤姆创建了标记。现在,杰瑞可以使用 Git 标记命令和 –l 选项查看所有可用标记。
Tom created tags. Now, Jerry can view all the available tags by using the Git tag command with –l option.
[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
杰瑞使用 Git show 命令,后跟其标记名称来查看标记的更多详细信息。
Jerry uses the Git show command followed by its tag name to view more details about tag.
[jerry@CentOS src]$ git show Release_1_0
以上命令将生成以下结果 −
The above command will produce the following result −
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
Delete Tags
汤姆使用以下命令从本地和远程存储库中删除标记。
Tom uses the following command to delete tags from the local as well as the remote repository.
[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 Operation
补丁是一个文本文件,其内容类似于 Git diff,但在代码的同时,还包含有关提交的元数据;例如,提交 ID、日期、提交消息等。我们能够从提交中创建一个补丁,其他人能够将其应用到自己的存储库中。
Patch is a text file, whose contents are similar to Git diff, but along with code, it also has metadata about commits; e.g., commit ID, date, commit message, etc. We can create a patch from commits and other people can apply them to their repository.
杰瑞为自己的项目实现了 strcat 函数。杰瑞能够创建他的代码的路径并将它发送给汤姆。然后,他能够将收到的补丁应用到自己的代码中。
Jerry implements the strcat function for his project. Jerry can create a path of his code and send it to Tom. Then, he can apply the received patch to his code.
杰瑞使用 Git format-patch 命令为最新的提交创建了一个补丁。如果你想要为某个特定的提交创建补丁,那么请与格式化补丁命令一起使用 COMMIT_ID 。
Jerry uses the Git format-patch command to create a patch for the latest commit. If you want to create a patch for a specific commit, then use COMMIT_ID with the format-patch command.
[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 文件。汤姆能够使用此补丁修改他的文件。Git 提供了两个命令应用补丁 git am*and *git apply 。 Git apply 修改本地文件而不会创建提交,而 git am 修改文件并创建提交。
The above command creates .patch files inside the current working directory. Tom can use this patch to modify his files. Git provides two commands to apply patches git am*and *git apply, respectively. Git apply modifies the local files without creating commit, while git am modifies the file and creates commit as well.
要应用补丁并创建提交,请使用以下命令:
To apply patch and create commit, use the following command −
[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 命令查看修改。
The patch gets applied successfully, now we can view the modifications by using the git diff command.
[tom@CentOS src]$ git diff
以上命令将生成以下结果 −
The above command will produce the following result −
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 - Managing Branches
分支操作允许创建另一行开发内容。我们可以使用此操作将开发进程分叉到两个不同的方向。例如,我们为 6.0 版本发布了一个产品,我们可能希望创建一个分支,以便使 7.0 功能的开发与 6.0 的 bug 修复保持分离。
Branch operation allows creating another line of development. We can use this operation to fork off the development process into two different directions. For example, we released a product for 6.0 version and we might want to create a branch so that the development of 7.0 features can be kept separate from 6.0 bug fixes.
Create Branch
Tom 使用 git branch <branch name> 命令创建一个新分支。我们可以从现有分支创建一个新分支。我们可以使用特定的提交或标签作为起点。如果没有提供任何特定提交 ID,那么将以 HEAD 为起点创建分支。
Tom creates a new branch using the git branch <branch name> command. We can create a new branch from an existing one. We can use a specific commit or tag as the starting point. If any specific commit ID is not provided, then the branch will be created with HEAD as its starting point.
[jerry@CentOS src]$ git branch new_branch
[jerry@CentOS src]$ git branch
* master
new_branch
新分支已创建;Tom 使用 git branch 命令列出可用分支。Git 在当前签出的分支前显示星号标记。
A new branch is created; Tom used the git branch command to list the available branches. Git shows an asterisk mark before currently checked out branch.
下面显示创建分支操作的图片表示形式 −
The pictorial representation of create branch operation is shown below −
Switch between Branches
Jerry 使用 git checkout 命令在分支之间切换。
Jerry uses the git checkout command to switch between branches.
[jerry@CentOS src]$ git checkout new_branch
Switched to branch 'new_branch'
[jerry@CentOS src]$ git branch
master
* new_branch
Shortcut to Create and Switch Branch
在上面的示例中,我们分别使用了两个命令创建并切换分支。Git 为 checkout 命令提供 –b 选项;此操作创建一个新分支,然后立即切换到新分支。
In the above example, we have used two commands to create and switch branches, respectively. Git provides –b option with the checkout command; this operation creates a new branch and immediately switches to the new branch.
[jerry@CentOS src]$ git checkout -b test_branch
Switched to a new branch 'test_branch'
[jerry@CentOS src]$ git branch
master
new_branch
* test_branch
Delete a Branch
可以通过使用 –D 选项和 git 分支命令删除分支。但在删除现有分支之前,请切换到另一个分支。
A branch can be deleted by providing –D option with git branch command. But before deleting the existing branch, switch to the other branch.
Jerry 目前在 test_branch ,他希望删除该分支。因此,他切换分支并删除分支,如下所示。
Jerry is currently on test_branch and he wants to remove that branch. So he switches branch and deletes branch as shown below.
[jerry@CentOS src]$ git branch
master
new_branch
* test_branch
[jerry@CentOS src]$ git checkout master
Switched to branch 'master'
[jerry@CentOS src]$ git branch -D test_branch
Deleted branch test_branch (was 5776472).
现在,Git 只会显示两个分支。
Now, Git will show only two branches.
[jerry@CentOS src]$ git branch
* master
new_branch
Rename a Branch
Jerry 决定在他的字符串操作项目中添加对宽字符的支持。他已经创建了一个新分支,但分支名称不恰当。因此,他使用 –m 选项,后跟 old branch name 和 new branch name ,更改分支名称。
Jerry decides to add support for wide characters in his string operations project. He has already created a new branch, but the branch name is not appropriate. So he changes the branch name by using –m option followed by the old branch name and the new branch name.
[jerry@CentOS src]$ git branch
* master
new_branch
[jerry@CentOS src]$ git branch -m new_branch wchar_support
现在,git branch 命令将显示新的分支名称。
Now, the git branch command will show the new branch name.
[jerry@CentOS src]$ git branch
* master
wchar_support
Merge Two Branches
杰瑞实现了一个返回宽字符长度的字符串长度的函数。现在代码将显示如下所示:
Jerry implements a function to return the string length of wide character string. New the code will appear as follows −
[jerry@CentOS src]$ git branch
master
* wchar_support
[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src
[jerry@CentOS src]$ git diff
上述命令会产生以下结果 −
The above command produces the following result −
t a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..8fb4b00 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,4 +1,14 @@
#include <stdio.h>
+#include <wchar.h>
+
+size_t w_strlen(const wchar_t *s)
+
{
+
const wchar_t *p = s;
+
+
while (*p)
+ ++p;
+ return (p - s);
+
}
在测试后,他提交并推送下代码更改到新的分支。
After testing, he commits and pushes his changes to the new branch.
[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 w_strlen function to return string lenght of wchar_t
string'
[wchar_support 64192f9] Added w_strlen function to return string lenght of wchar_t string
1 files changed, 10 insertions(+), 0 deletions(-)
请注意,杰瑞将这些更改推送到新的分支,这才使他使用分支名称 wchar_support ,而不是 master 分支。
Note that Jerry is pushing these changes to the new branch, which is why he used the branch name wchar_support instead of master branch.
[jerry@CentOS src]$ git push origin wchar_support <−−− Observer branch_name
上述命令将产生以下结果。
The above command will produce the following result.
Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 507 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
* [new branch]
wchar_support -> wchar_support
在提交更改后,新分支将显示如下所示:
After committing the changes, the new branch will appear as follows −
汤姆很想知道杰瑞在他的私有分支中做了什么,并从 wchar_support 分支中查看了日志。
Tom is curious about what Jerry is doing in his private branch and he checks the log from the wchar_support branch.
[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
[tom@CentOS src]$ git log origin/wchar_support -2
上述命令将产生以下结果。
The above command will produce the following result.
commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 16:10:06 2013 +0530
Added w_strlen function to return string lenght of wchar_t string
commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530
Removed executable binary
通过查看提交消息,汤姆得知杰瑞实现了一个宽字符的 strlen 函数,他还希望在主分支中实现相同的功能。他决定不重新实现,而是通过将自己的分支与主分支合并来采用杰瑞的代码。
By viewing commit messages, Tom realizes that Jerry implemented the strlen function for wide character and he wants the same functionality in the master branch. Instead of re-implementing, he decides to take Jerry’s code by merging his branch with the master branch.
[tom@CentOS project]$ git branch
* master
[tom@CentOS project]$ pwd
/home/tom/top_repo/project
[tom@CentOS project]$ git merge origin/wchar_support
Updating 5776472..64192f9
Fast-forward
src/string_operations.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
在合并操作后,主分支将显示如下所示:
After the merge operation, the master branch will appear as follows −
现在,分支 wchar_support 已与主分支合并。我们可以通过查看提交消息或通过查看对 string_operation.c 文件所做的修改来验证这一点。
Now, the branch wchar_support has been merged with the master branch. We can verify it by viewing the commit message or by viewing the modifications done into the string_operation.c file.
[tom@CentOS project]$ cd src/
[tom@CentOS src]$ git log -1
commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
Author: Jerry Mouse
Date: Wed Sep 11 16:10:06 2013 +0530
Added w_strlen function to return string lenght of wchar_t string
[tom@CentOS src]$ head -12 string_operations.c