查看原文
其他

让你一场 Chat 学会 Git

2017-12-19 王俊生 GitChat技术杂谈

本文来自作者 王俊生 在 GitChat 上分享 「让你一场 Chat 学会 Git」,「阅读原文」查看交流实录。

「文末高能」

编辑 | 哈比

一、Github 基础

什么是 Git?

git 是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)(Linux 之父)创作,于 2005 年发布。最初目的是为更好地管理 Linux 内核开发。

Git 在本地磁盘上就保存着所有有关当前项目的历史更新,处理速度快;Git 中的绝大多数操作都只需要访问本地文件和资源,不用实时联网。

Git 客户端

TortoiseGit 是一个 Git 版本控制客户端,作为 Microsoft Windows 的外壳扩展实现,用户界面友好,大多数人应该用过 TortoiseSvn;

MsysGit 是一个轻量级的 Git 工具集,可以进行各种 Git 操作,MsysGit 又分为简单的界面 Git GUI,和命令行 Git Bash,我们这节课主要通过 Git Bash 来演示。

Git 服务端:GitHub 和 Gitlab

GitHub 是一个共享虚拟主机服务,用于存放使用 Git 版本控制的软件代码和内容项目;允许用户跟踪其他用户、组织、软件库的动态,对软件代码的改动和 bug 提出评论。

GitLab 是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目,拥有与 Github 类似的功能,能够浏览源代码,管理缺陷和注释。

Git 基本概念

三种工作区域

  1. Git 的本地仓库:在 .git 目录中;

  2. 工作区:用户操作目录;

  3. 暂存区:在 .git 目录中。

三种状态

  1. 已提交(committed):该文件已经被安全地保存在本地仓库中;

  2. 已修改(modified):修改了某个文件,但还没有提交保存;

  3. 已暂存(staged):把已修改的文件放在下次提交时要保存的清单中。


注:状态转换图示如下

Git 分支初识

  1. Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。

  2. Git 会使用 master 作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master 分支,它在每次提交的时候都会自动向前移动。

  3. Git 鼓励在工作流程中频繁使用分支与合并。

二、Git 工作流程

git 的工作流程见下图,这是最标准的 git 使用流程,我们可以看到 git 是通过对各分支的维护来规范工作的。

首先有一条 master 分支,这是发布稳定版,一般不会对 master 进行修改。

当有新需求的时候,从 master 上分出一条 develop 分支,具体开发人员在从 develop 上分出自己具体 feature 分支,开发完毕后合并回 develop 分支,测试人员从 develop 分支分出 release 分支进行测试,没有问题了合并到 master 分支发布。

如果线上有 bug 需要处理,则从 master 上分出 hotfix 分支,用来解决 bug。


三、Git 基本操作

配置用户名和邮件

打开 git bash,配置命令:

git config --global user.name "your name" git config --global user.email "your email"

创建版本库

版本库又名仓库,英文名 repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被

Git 管理起来:

新建目录初始化:

mkdir testgit cd testgit

从当前目录初始化:

$ git init

查看仓库状态:

git status

添加到暂存区:

git add fileA fileB fileC ....

提交到本地仓库:

git commit -m “remarks”

查看修改内容(工作区和仓库的区别):

git diff (file)

查看版本(参数可以简化版本信息,commit id 和备注):

git log --pretty=oneline

版本回退

在 Git 中,用 HEAD 表示当前版本,也就是最新的提交 commit id,上一个版本就是 HEAD^,上上一个版本就是 HEAD^^,当然往上 100 个版本写 100 个 ^ 比较容易数不过来,所以写成 HEAD~100。

回退到上一个版本 :

git reset --hard HEAD^

丢弃工作区的修改(撤销):

git checkout -- file

删除文件:

  1. 正确操作:git rm file    git commit -m “remove      file”(文件被删除)

  2. 操作失误:git checkout — file(文件被恢复)

查看当前分支:

git branch (-a)

新建分支:

git branch develop(只是新建了一条分支,并未切换)

切换分支:

git checkout develop

新建并切换分支:

git checkout -b feature(相当于 3.10 和 3.11 两步操作)

删除分支:

git branch -d feature(注意:不能删除当前所在分支)

合并分支 (—no-ff 参数,表示禁用 Fast forward):

git checkout develop  &&  git merge feature(把 feature 分支合并到 develop 分支)

注:

  1. 因为我们创建 Git 版本库时,Git 自动为我们创建了唯一一个 master 分支,
    所以默认 git commit 就是往 master 分支上提交更改。

  2. 如果要丢弃一个没有被合并过的分支,可以通过git branch -D <branch>强行删除。

  3. 建立本地分支和远程分支的关联,使用 git branch —set-upstream branch-name origin/branch-name。

Git 基本操作—-和远程服务器交互(一)

添加远程服务器:

git remote add dcmsStatics4.5git(别名)http://gitlab.cephchina.com/ccod_project/dcmsstatics4-5git.git

查看远程服务器的相关信息:

git remote -v git remote show dcmsStatic4.5git

重命名远程仓库信:

git remote rename demo test

删除远程仓库:

git remote rm test

注:由于远程库是空的,我们第一次推送 master 分支时,加上了-u 参数,Git 不但会把本地的 master 分支内容推送到远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令。

之后,只要本地作了提交,就可以通过命令把本地 master 分支的最新修改推送至 GitLab:

git push dcmsStatic4.5git master

远程仓库

从远程仓库获取数据:

  • git fetch origin  develop —-  只是获取远程仓库的数据至 .git 目录,并未 merge 本地

  • git merge origin/develop—- 把获取的远程仓库的数据手工 merge 至当前分支

  • git pull origin develop——  获取远程仓库的数据,并自动 merge 至当前的分支,相当于以上两步

合并两个不同的项目:

allow-unrelated-histories

把本地仓库的内容推送到远程库上:

git push (-u) demo develop(从 svn 迁移到 gitlab 注意路径,要确保路径正确)

注:

从远程分支 checkout 出来的本地分支,称为跟踪分支 (tracking branch)。跟踪分支是一种和远程分支有直接联系的本地分支。

在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。

在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。

这正是 git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如 origin 上除了 master 之外的其它分支。

Git 基本操作:和远程服务器交互(二)

从远程库克隆:

  1. 从 svn 克隆 git svn clone 地址;

  2. 从 git 远程库上克隆:git clone 地址。

在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name

四、Git 标签

git 标签,通常用来给分支做标记,如标记一个版本号。

创建

标签分类

轻量级标签:

git tag <tagname> commit id

带说明标签:

git tag -a  <tagname> commit id git tag -m <msg> <tagname> commit id

带签名的标签(GPG 加密,需安装配置):

git tag -s  <tagname> commit id git tag -u  <key-id> commit id

查看和删除

查看标签:

git tag git tag –n git show <tagname>

删除标签:

git tag -d <tagname>

共享标签

向上游版本库提交标签:

git push origin <tagname> git push origin  --tags

删除远程版本库的标签:

git push origin :tag2

五、补充

Git 分支冲突解决

如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起 Git 作了合并,但没有提交,它会停下来等你解决冲突。

可以用 git status 查阅哪些文件在合并时出现冲突。Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。

注:用带参数的 git log 也可以看到分支的合并情况:

git log --graph --pretty=oneline --abbrev-commit

冲突标记 <<<<<<< (7 个 <)与 ======= 之间的内容是 我 的修改,======= 与>>>>>>> 之间的内容是别人的修改。 

最简单的编辑冲突的办法,就是直接编辑冲突了的文件,把冲突标记删掉,把冲突解决正确。

特殊场景

场景:当接到一个新的 bug,急需解决,但是目前工作想保留。

方法:Git 还提供了一个 stash 功能,可以把当前工作现场 “储藏” 起来,等以后恢复现场后继续工作。比如你正在 dev 分支开发,突然接到 master 上有一个特别急的 bug 需要解决,这时就可以把当前 dev 的工作现场 “储藏” 起来。

首先 “储藏”dev 的工作现场 git status,然后从 master 创建临时分支:

git checkout master git checkout -b issue-101

现在修复 bug,然后提交:

git add readme.md git commit -m "fix bug 101"

修复完成后,切换到 master 分支,并完成合并,最后删除 issue-101 分支:

git checkout master git merge --no-ff -m "merged bug fix 101" issue-101

接着回到 dev 分支干活了!

git checkout dev git status

工作区是干净的,刚才的工作现场存到哪去了?用 git stash list 命令看看:

git stash list

工作现场还在,Git 把 stash 内容存在某个地方了,但是需要恢复一下,有两个办法:

一是用 git stash apply 恢复,但是恢复后,stash 内容并不删除,你需要用 git stash drop 来删除;另一种方式是用 git stash pop,恢复的同时把 stash 内容也删了:

git stash pop

再用 git stash list 查看,就看不到任何 stash 内容了。你可以多次 stash,恢复的时候,先用 git stash list 查看,然后恢复指定的 stash,用命令:

git stash apply stash@{0}

远程分支

提交本地 test 分支作为远程的 develop 的分支:

git push origin develop:test

删除远程的 test 分支,但是本地还会保存的:

git push origin :test

忽略特殊文件

我们在开发过程中,有一些文件是不需要提交的,但是 git 总显示这部分文件会让人很不舒服,这时我们就可以通过编辑 .gitignore 文件来使不需要提交的文件不在提示,编写要忽略的文件。

下列内容是 Java 开发者经常用到的:

# java: *.class # My configurations: db.ini deploy_key_rsa

注:# 此为注释,这行内容将被 Git 忽略

# 忽略所有 .a 结尾的文件 *.a # 但 lib.a 除外 !lib.a # 仅仅忽略项目根目录下的 TODO 文件, /TODO # 忽略 build/ 目录下的所有文件 build/ # 忽略 doc/notes.txt doc/*.txt

配置别名

git 命令可不可以根据自己的特点配置别名呢,当然是可以的,这样做能提高工作效率,下列是一些简单的例子。

git config --global alias.st status(git st=git status) git config --global alias.co checkout(git co=git checkout) git config --global alias.ci commit(git ci=git commit) git config --global alias.br branch(git br=git branch) git config --global alias.last 'log -1'(git lat= git log -l) git config --global alias.unstage 'reset HEAD'(git unstage=git reset HEAD) git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"(这个大家可以亲自试试,特别炫)

切换用户

查看当前配置(用户):

git config --list

修改配置:打开全局的 .gitconfig 文件:vi ~/.gitconfig;然后在文件中直接修改。

近期热文

接口测试工具 Postman 使用实践

如何基于 Redis 构建应用程序组件

深度学习在摄影技术中的应用与发展

这样做,你的面试成功率将达到 90%

如何用 TensorFlow 让一切看起来更美?

Web 安全:前端攻击 XSS 深入解析


「阅读原文」看交流实录,你想知道的都在这里

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存