关于git:Git高级使用教程

74次阅读

共计 7743 个字符,预计需要花费 20 分钟才能阅读完成。

Git 与 SVN 区别

Git 是一个开源的分布式版本控制系统,用于麻利高效地解决任何或小或大的我的项目。Git 是 Linus Torvalds 为了帮忙治理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与罕用的版本控制工具 CVS, Subversion 等不同,它采纳了分布式版本库的形式,不用服务器端软件反对。

GIT 不仅仅是个版本控制系统,它也是个内容管理系统(CMS), 工作管理系统等。如果你是一个具备应用 SVN 背景的人,你须要做肯定的思维转换,来适应 GIT 提供的一些概念和特色。Git 与 SVN 区别点:
1、GIT 是分布式的,SVN 不是:这是 GIT 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最外围的区别。
2、GIT 把内容按元数据形式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息暗藏在一个相似.svn,.cvs 等的文件夹里。
3、GIT 分支和 SVN 的分支不同:分支在 SVN 中一点不特地,就是版本库中的另外的一个目录。
4、GIT 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 GIT 短少的最大的一个特色。
5、GIT 的内容完整性要优于 SVN:GIT 的内容存储应用的是 SHA- 1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时升高对版本库的毁坏。

Git 工作原理

Git 工作流程能够分一下步骤:

  • 克隆 Git 资源作为工作目录;
  • 在克隆的资源上增加或批改文件;
  • 如果其他人批改了,你能够更新资源;
  • 在提交前查看批改。提交批改;
  • 在批改实现后,如果发现错误,能够撤回提交并再次批改并提交;

Git 工作区、暂存区和版本库:

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫 stage, 或 index。个别寄存在 ”git 目录 ” 下的 index 文件(.git/index)中,所以咱们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个暗藏目录.git,这个不算工作区,而是 Git 的版本库。

常见操作

全局配置用户信息

git config --global user.name "smyhvae"

git config --global user.email "smyhvae@163.com"

Git 创立仓库

git init repository

如果当前目录下有几个文件想要纳入版本控制,须要先用 git add 命令通知 Git 开始对这些文件进行跟踪,而后提交:

$ git add *.c
$ git add README
$ git commit -m 'initial project version'

从现有仓库克隆

$ git clone git://github.com/test/test.git

Git 基本操作命令

git init
创立我的项目命令,在目录中创立新的 Git 仓库。你能够在任何时候、任何目录中这么做,齐全是本地化的。在目录中执行 git init,就能够创立一个 Git 仓库。

$ mkdir test
$ cd test
$ git init

git clone
应用 git clone 拷贝一个 Git 仓库到本地,让本人可能查看该我的项目,或者进行批改。

$ git clone git://github.com/test/test.git

git push
其作用是将本地分支的更新推送到近程主机

$ git push < 近程主机名 > < 本地分支名 >:< 近程分支名 >

git pull
其作用是将近程主机更新到本地分支

$ git pull < 近程主机名 > < 本地分支名 >:< 近程分支名 >

git add
git add 命令可将该文件增加到缓存,如咱们增加以下两个文件:

$ touch README
$ touch hello.php
$ ls
README      hello.php
$ git status -s
?? README
?? hello.php
$ 

git status
命令用于查看我的项目的以后状态

$ git add README hello.php 

$ git status -s
A  README
A  hello.php
$ 

git diff
git diff 命令显示已写入缓存与已批改但尚未写入缓存的改变的区别。git diff 有两个次要的利用场景:
尚未缓存的改变:git diff
查看已缓存的改变:git diff –cached
查看已缓存的与未缓存的所有改变:git diff HEAD
显示摘要而非整个 diff:git diff –stat

$ git status -s
A  README
AM hello.php
$ git diff
diff --git a/hello.php b/hello.php

git commit

应用 git add 命令将想要快照的内容写入了缓存,而执行 git commit 记录缓存区的快照。Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步须要配置用户名和邮箱地址。

$ git config --global user.name 'admin'
$ git config --global user.email admin@qq.com

$ git add hello.php
$ git status -s
A  README
A  hello.php
$ git commit -m 'test comment from test.cn'
[master (root-commit) 85fc7e7] test comment from test.cn
 2 files changed, 4 insertions(+)
 create mode 100644 README
 create mode 100644 hello.php

当初咱们曾经记录了快照。如果咱们再执行 git status:

$ git status
# On branch master
nothing to commit (working directory clean)

git log
查看历史提交记录

$ git log
commit 88afe0e02adcdfea6844bb627de97da21eb10af1
Merge: 14b4dca d7e7346
Author: admin
Date:   Sun Mar 1 15:03:42 2020 +0800

    Merge branch 'change_site'
    
    Conflicts:
        test.txt

commit 14b4dcadbdc847207651d5a9fae0d315057f346e
Author: admin
Date:   Sun Mar 1 14:53:15 2015 +0800

git tag
能够应用 git tag 给打上标签

git reset HEAD
命令用于勾销缓存已缓存的内容。

$ git status -s
 M README
 M hello.php
$ git add .
$ git status -s
M  README
M  hello.pp
$ git reset HEAD -- hello.php 
Unstaged changes after reset:
M hello.php
$ git status -s
M  README
 M hello.php

git rm
将文件从缓存区中移除。

$ git rm hello.php 
rm 'hello.php'
$ ls
README

git mv
命令做得所有事件就是 git rm –cached,重命名磁盘上的文件,而后再执行 git add 把新文件增加到缓存区。因而,尽管有 git mv 命令,但它有点多余。

分支的合并

场景:基于 master 分支的代码,开发一个新的个性

如果你间接在 master 分支上开发这个新个性,是不好的,万一你在开发 个性 1 的时候,领导忽然又要叫你去开发 个性 2 ,就不好解决了。难道开发的两个个性都提交到 master?一会儿提交个性 1 的 commit,一会儿提交个性 2 的 commit?这会导致 commit 记录很凌乱。

所以,我给你的倡议做法是:给每个个性都独自建一个的新的分支。

比如说,我专门给 个性 1 建一个分支feature_item_recommend。具体做法如下:

(1)基于 master 分支,创立一个新的分支,起名为feature_item_recommend

$ git checkout -b feature_item_recommend

Switched to a new branch 'feature_item_recommend'

下面这行命令,相当于:

$ git branch feature_item_recommend    // 创立新的分支

$ git checkout feature_item_recommend  // 切换到新的分支

(2)在新的分支 feature_item_recommend 上,实现开发工作,并 commit、push。

(3)将分支 feature_item_recommend 上的开发进度 合并 到 master 分支:

$ git checkout master  // 切换到 master 分支

$ git merge feature_item_recommend    // 将分支 feature_item_recommend 的开发进度合并到 master 分支

合并之后,master分支和 feature_item_recommend 分支会指向同一个地位。

(3)删除分支feature_item_recommend

既然 个性 1 开发完了,也释怀地提交到 master 了,那咱们就能够将这个分支删除了。

git branch -d feature_item_recommend

留神,咱们以后是处于 master 分支的地位,来删除 feature_item_recommend 分支。如果以后是处于 feature_item_recommend 分支,是没方法删除它本人的。

同理,当我转身去开发 个性 2 的时候,也是采纳同样的步骤。

合并分支时,如果存在分叉

比如说下面这张图中,最早的时候,master 分支是位于 C2 节点。我基于 C2 节点,new 出一个新的分支 iss53,我在iss53 上提交了好几个 commit。

当初,我筹备把 iss53 上的几个 commit 合并到 master 上,此时发现,master 分支曾经后退到 C4 了。那该怎么合并呢?

合并的命令依然是:

$ git checkout master

$ git merge iss53

解释

这次合并的实现,并不同于简略的并入形式。这一次,我的开发历史是从更早的中央开始分叉的。

因为以后 master 分支所指向的 commit (C4)并非想要并入分支(iss53)的间接先人,Git 不得不进行一些解决。就此例而言,Git 会用两个分支的末端(C4 和 C5)和它们的独特先人(C2)进行一次简略的三方合并计算。

Git 没有简略地把分支指针右移,而是对三方合并的后果作一新的快照,并主动创立一个指向它的 commit(C6)(如下图所示)。咱们把这个非凡的 commit 称作合并提交(mergecommit),因为它的先人不止一个。

值得一提的是 Git 能够本人裁决哪个独特先人才是最佳合并根底;这和 CVS 或 Subversion(1.5 当前的版本)不同,它们须要开发者手工指定合并根底。所以此个性让 Git 的合并操作比其余零碎都要简略不少。

解决合并时产生的抵触

如果 feature1 和 feature2 批改的是同一个文件中 代码的同一个地位,那么,把 feature1 合并到 feature2 时,就会产生抵触。这个抵触须要人工解决。步骤如下:

(1)手动批改文件:手动批改抵触的那个文件,决定到底要用哪个分支的代码。

(2)git add:解决好抵触后,输出 git status,会提醒Unmerged paths。这个时候,输出git add 即可,示意:批改抵触胜利,退出暂存区

(3)git commit 提交。

而后,咱们能够持续把 feature1 分支合并到 master 分支,最初删除 feature1、feature2。

留神:两个分支的同一个文件的不同中央合并时,git 会主动合并,不会产生抵触。

比方分支 feture1 对 index.html 原来的第二行之前退出了一段代码。
分支 feature2 对 index.html 在原来的最初一行的前面退出了一段代码。
这个时候在对两个分支合并,git 不会产生抵触,因为两个分支是批改同一文件的不同地位。
git 主动合并胜利。不论是 git 主动合并胜利,还是在人工解决抵触下合并胜利,提交之前,都要对代码进行测试。

日常操作积攒

批改明码(曲线救国)

网上查了很久,没找到答案。最终,在 cld 童鞋的提醒下,采取如下形式进行曲线救国。

# 设置以后仓库的用户名为空
git config  user.name ""

而后,当咱们再输出 git pull 等命令行时,就会被要求从新输出 新的 账号密码。此时,明码就能够批改胜利了。最初,咱们还要输出如下命令,还原以后仓库的用户名:

git config user.name "smyhvae"

批改曾经 push 的某次 commit 的作者信息

曾经 push 的记录,如果要批改作者信息的话,只能 通过 –force 命令。

branch1的某个 commit1 合并到 branch2 当中

切换到 branch2 中,而后执行如下命令:

git cherry-pick commit1

20200118- 批改 GitHub 已提交的用户名和邮箱

在执行 ./email.sh 后,如果呈现 permission denied 的谬误,能够先执行chmod 777 email.sh,批改文件的权限。

20200520- 将 Git 我的项目迁徙到另一个仓库

咱们假如旧仓库的项目名称叫old-repository,新仓库的项目名称叫new-repository。操作如下:

(1)创立旧仓库的裸克隆:

git clone --bare https://github.com/exampleuser/old-repository.git

执行上述命令后,会在本地生成一个名叫 old-repository.git的文件夹。

(2)迁徙到新仓库:

cd old-repository.git

git push --mirror https://github.com/exampleuser/new-repository.git

这样的话,我的项目就曾经迁徙到新仓库了。

留神,咱们 不须要 手动新建一个空的新仓库,当咱们执行上述命令之后,新仓库就曾经主动创立好了。

参考链接:

  • 复制仓库
  • Git 本地仓库和裸仓库

Git 服务器搭建

咱们将以 Centos 为例搭建 Git 服务器。

1、装置 Git

$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git

创立一个 git 用户组和用户,用来运行 git 服务:

$ groupadd git
$ adduser git -g git

2、创立证书登录
收集所有须要登录的用户的公钥,公钥位于 id_rsa.pub 文件中,把咱们的公钥导入到 /home/git/.ssh/authorized_keys 文件里,一行一个。如果没有该文件创建它:

$ cd /home/git/
$ mkdir .ssh
$ chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys

3、初始化 Git 仓库
首先咱们选定一个目录作为 Git 仓库,假设是 /home/gitrepo/hello.git,在 /home/gitrepo 目录下输出命令:

$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo

$ git init --bare hello.git
Initialized empty Git repository in /home/gitrepo/hello.git/

以上命令 Git 创立一个空仓库,服务器上的 Git 仓库通常都以.git 结尾。而后,把仓库所属用户改为 git:

$ chown -R git:git w3cschoolcn.git

4、克隆仓库

$ git clone git@192.168.45.4:/home/gitrepo/w3cschoolcn.git
Cloning into 'w3cschoolcn'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

192.168.45.4 为 Git 所在服务器 ip,你须要将其批改为你本人的 Git 服务 ip。这样咱们的 Git 服务器装置就实现了,接下来咱们能够禁用 git 用户通过 shell 登录,能够通过编辑 /etc/passwd 文件实现。找到相似上面的一行:

git:x:503:503::/home/git:/bin/bash
改为:git:x:503:503::/home/git:/sbin/nologin

Git 客户端举荐

TortoiseGit

对这只小乌龟预计没有开发人员会不意识,SVN 的超宽泛应用也使得这个超好用的 Svn 客户端成了简直每个开发人员的桌面必备软件。小乌龟只提供 Windows 版本,提供中文版反对的,对于中国的开发者来说者相对是福音。

小乌龟的文件管理器右键菜单的操作形式对于老手来说十分的容易上手,而且容易了解。
TortoiseGit(git 客户端工具)

Sublime Merge for Mac(git 客户端工具)
领有简洁的界面,三向合并工具,弱小搜寻性能,语法突出显示等特点,Sublime Merge for Mac 是一款 Git 客户端工具,实现了 Sublime。与 Sublime Text 的制造商会面。一个疾速的用户界面,三向合并工具,并排差别,语法高亮等等。Stage Files,iSwiftHunks 和 Lines 没有期待 – Sublime Merge 真的十分十分快。

Sublime Merge for Mac(git 客户端工具)

GitHub for Desktop

寰球开发人员交友俱乐部提供的弱小工具,功能完善,使用方便。对于应用 GitHub 的开发人员来说是十分便捷的工具。界面洁净,用起来十分棘手,下面的这条 timeline 十分丑陋,也能够间接提交 PR。

惟一让我悲观的是 GitHub for Desktop 不带三方合并工具,你必须本人手动解决抵触才能够。– 收费
– 同时反对 Windows 和 Mac:对于须要常常在不同的操作系统间切换的开发人员来说十分不便。
– 丑陋的界面:作为每天盯着看的工具,颜值是十分重要的
– 反对 Pull Request:间接从客户端提交 PR,很不便
– Timeline 反对:间接在工夫线上显示每次提交的工夫点和大小
– 反对 git LFS:存储大文件更加节俭空间和高效
– 不反对三方合并:须要借助第三方工具才行

Source Tree

SourceTree 是老牌的 Git GUI 管理工具了,也号称是最好用的 Git GUI 工具。我的体验是的确弱小,功能丰富,基本操作和高级操作都设计得十分晦涩,适宜初学者上手。

这个工具很有特色的一个性能就是反对 Git Flow,你能够一键创立 Git Flow 的工作流。Git Flow 是十分高效的团队合作模型和流程,Git 的一大特色就是灵便轻量的分支,但如何在本人的团队中用好这个性能来匹配本人的研发流程是个问题。内置 Git Flow 让那些不太熟悉的开发人员也能够很快上手,并且将研发的业务流程固化在工具中,能够说是十分贴心的设计。

Source Tree(git 客户端工具)

SmartGit

商业用途免费,个人用户收费:

举荐书籍

  • 《pro.git 中文版》

正文完
 0