git的学习笔记-入门

PS:小白的入门笔记,希望能有用,主要参考廖君Git教程

操作环境说明:

  • github仓库 https://github.com/zhanghlHUST/figureForMarkdown,作为名词说明的示例
  • 本地工作区 E:\github\figureForMarkdown
  • 操作系统 win10 64位
  • Github Desktop 3.3.4.0
  • Windows PowerShell(x86) 运行 Git Shell 作为命令行工具

参考:
廖君Git教程
git pro
图解Git
知乎-分支操作的一些讨论

简单粗暴的注意事项:

  • 使用git checkout删除工作区修改、撤销删除、切换分支时,一定要注意备份当前工作区的内容,git会采用仓库内容直接更新工作区,造成工作区修改的丢失

为什么学 git ?

  • 版本控制,git、CVS 及 SVN 都能做到
  • 分布式的合作开发的控制
  • github 的开放的资源

git 的版本控制

工作时从 版本库中提取文件到 工作区进行文件的创建、编辑、修改、删除等操作,工作 完成后提交至版本库,由版本库跟踪文件的修改历史,所有的版本控制系统 只能跟踪文本文件的改动,版本控制系统可以告诉你每次的改动,如 txt 文件、网页、代码等。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但 没法跟踪二进制文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。

知识结构

git的知识结构
git的知识结构

后续学习任务

  • 结合《Falsk Web 开发》对 git 在实际项目的控制过程进行实战,写成总结
  • github 的正确使用姿势,写成总结
  • git 的底层机制的学习,特别是 diffcheckoutresetbranchcommit 这几个概念的深入理解,写成总结

工作区及版本库的概念

github概念
github概念
  • 工作区: 就是你在电脑里能看到的目录,即 E:\github\figureForMarkdown
  • 版本库: 工作区有一个隐藏目录.git,即本地的Git的版本库,当前仓库下,如果没有任何的提交,那么版本库就是对应上次提交后的内容。主要包含暂存区index,git自动创建的第一个分支master以及指向master的指针HEAD
本地版本库文件列表
本地版本库文件列表
  • 暂存区: git的版本库里面最重要的就是称为stage(或index)的暂存区,实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。在这个虚拟工作区的目录树中,记录了文件名、文件的状态信息(时间戳、文件长度等),文件的内容并不存储其中,而是保存在Git对象库(.git/objects)中,文件索引建立了文件和对象库中对象实体之间的对应。如果当前仓库,有文件更新,并且使用git add命令,那么这些更新就会出现在暂存区中。

操作

创建版本库(by shell)

  • 首先,选择一个合适的地方,创建一个空目录,mkdir learngit,cd learngit,pwd OUTPUT: E:\github\learngit,windows系统中各级目录名中最好不要使用中文
  • 通过git init 将该目录编程git可以管理的仓库,OUTPUT: Initialized empty Git repository in E:/github/learngit/.git/,至此仓库生成目录下包含 .git 目录用来跟踪管理版本库。ls -ah 查看隐藏的.git文件

创建版本库(by desktop)

+->Create-> 选择 Namelocal path -> Create repository

添加文件到版本库 (by shell)

git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的,git status查看

  • 在工作区 E:\github\learngit中创建 readme.txt 文件,编辑输入:
Git is a version control system.
Git is free software. 
  • 使用git add readme.txt 添加文件至仓库(暂存区index以及objects)。没有输出表示操作成功,可反复多次使用,可以同时添加多个文件;
  • 使用git commit -m 'wrote a readme file'将文件提交至当前分支,并添加描述信息,会显示分支当前的状态与暂存区的比较结果,-m后为本次提交说明

添加文件到版本库 (by Desktop)

Desktop没有先add到暂存区,然后commit到分支的概念,文件编辑后,直接查看 changes 查看文件的变化,勾选需要提交的变化,输入comment summary and descriptipn 提交

修改文件 (by Shell)

  • git status 命令可以让我们时刻掌握仓库当前的状态。
  • 工作区文件与仓库完全一致时,git status结果为:
On branch master
nothing to commit, working tree clean
即 没有待提交内容,工作目录是干净的
  • 工作区文件改变,如上修改 readme.txt, 改为 Git is a distributed version control system., git status结果为:
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working dir

        modified:   reademe.txt

no changes added to commit (use "git add" and/or "git commit -a")
 即 文件被修改,但是还未准备提交修改
  • 工作区文件修改,并git add提交至缓存区,git status结果为:

修改文件 (by Desktop)

与添加文件操作完全一致,客户端不严格区分暂存区与工作区

历史版本的操作

像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

查看历史纪录(by Shell)
  • git log命令显示从最近到最远的提交日志,可以看到两次操作,分别是创建文件,及修改文件,
  • git log --pretty=online 整理输出信息
将仓库撤回到指定版本

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。也可以直接使用 git log显示的 commit 版本号,且版本号没必要写全,前几位就可以了,Git会自动去找。

  • git reflog 查看历史commit的版本号
  • 参照廖君Git教程 设置三次提交
  • git reset --hard HEAD^ 将文件撤回到 add distributed 版本,并且 git log查看,add GPL已经消失,
  • git的版本撤回是将HEAD指针的指向,并更新工作区的文件。
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Mon Aug 19 17:51:55 2013 +0800

    wrote a readme file
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..."

        modified:   reademe.txt
  即 文件被修改,待提交
查看文件的对比区分
  • git diff 查看缓存区与工作区的文件的改变细节。
撤销修改
撤销工作区的修改(by Shell)
  • 当工作区的文件修改且该修改并未提交到暂存区,git checkout -- file 可以丢弃工作区的修改
  • 当工作区的文件修改已经提交到暂存区,又做了修改,git checkout -- file撤销修改就回到添加到暂存区后的状态。
  • 就是让这个文件回到最近一次 git commitgit add 时的状态。git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”
撤销暂存区的修改(by Shell)
  • git reset HEAD file 可以把暂存区的修改撤销掉(unstage),重新放回工作区
撤销工作区及暂存区的修改(by Desktop)
  • Destop 并未严格区分工作区与暂存区,changes -> 选择指定的修改 -> discard changes
撤销提交到本地版本库的修改(by Shell)
  • 上文中的将仓库撤回指定版本的操作,git reset --hard 版本号
撤销提交到本地版本库的修改(by Desktop)
  • History -> 选择指定的提交 -> revert
删除文件(by Shell)
  • git rm 相当于手动删除文件并提交至暂存区,然后 git commit -m "commit"至本地版本库
  • git checkout -- file 恢复误删的文件
删除文件(by Desktop)
  • 手动删除文件 -> changes -> 提交修改到版本库

本地仓库与远程仓库

github工作流程
github工作流程
  • 远程仓库就是在公网服务器上的仓库(repository),即 https://github.com/zhanghlHUST/figureForMarkdownGit是分布式版本控制系统, 同一个Git仓库,可以分布到不同的机器上,找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。Github用来提供Git仓库的托管服务,注册一个Github账号就免费获得Git远程仓库。

操作

设置 SSH-Key

github官网 头像下拉 -> Settings -> SSH and GPG keys -> SSH keys

创建远程仓库

在本地创建了一个Git仓库后,可以在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份又可以让其他人通过该仓库来协作,github上的仓库是公开的,可以选择缴费或者自己搭建远程仓库服务器的方式创建私有的仓库。

github官网 -> + -> new repository -> 输入Repository name -> 不要选 Initialize this repository with a README

为本地仓库添加远程仓库(by Shell)

在本地仓库运行 -> git remote add origin https://github.com/zhanghlHUST/learngit.git (添加后远程库的名字是origin)

为本地仓库添加远程仓库(by Desktop)

右上角Publish -> 输入 NameDescription -> 下拉选择 github 账号 -> Publish repository,之后按钮 Publish 会转变成 Sync

推送本地仓库内容到远程仓库(by Shell)

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们 第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改

在本地仓库运行 -> git push -u origin master
在本地仓库运行 -> git push origin devdev 分支推送至远程仓库 origin

什么分支需要推送?
  • master分支是主分支,因此要时刻与远程同步,保存程序的发行版本。
  • dev分支是开发分支,保存程序的主要开发版本,团队所有成员都需要在上面工作,所以也需要与远程同步;
  • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug
  • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

推送本地仓库内容到远程仓库(by Desktop)

右上角Sync,完全同步本地库与远程库,让两者保持一致,功能单一

创建远程 orgindev 分支到本地

git checkout -b dev origin/devdev分支上协作开发,就必须创建远程origindev分支到本地

从远程库克隆创建本地仓库(by Shell)

在本地仓库运行 -> git clone git@github.com:zhanghlHUST/learngit.git, 当从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin

从远程库克隆创建本地仓库(by Desktop)

+ -> Clone -> 选择 repository -> Clone repositoty -> 选择本地仓库目录

查看远程库的信息 (by Shell)

git remote, git remote -v 查看远程库的详细信息

合作开发的控制

分支的概念

引用 Git 分支 - 利用分支进行开发的工作流程

  • 合作开发的控制: 可以同时拥有多个开放的分支,每个分支用于完成特定的任务,随着开发的推进,可以随时把某个特性分支的成果并到其他分支中。
稳定性分支示意图
稳定性分支示意图
  • 维护不同程度的稳定性:通常在master分支中保留完全稳定的代码(通常是已经发布或者即将发布的代码),与此同时还有一个名为 master 或者 next 的分支 专门用于后续的开发或者测试,当 next 的新特性一旦进入某种稳定状态,就可以将新特性合并到master,同样设置 针对具体问题的特性分支(短期分支) topic,在确保指定特性分支能够通过所有测试之后将其合并到主干分支,等待后续的发布。
特性分支示意图
特性分支示意图
  • 如上图由下往上,起先我们在 master 工作到 C1,然后开始一个新分支 iss91 尝试修复 91 号缺陷,提交到 C6 的时候,又冒出一个解决该问题的新办法,于是从之前 C4 的地方又分出一个分支 iss91v2,干到 C8 的时候,又回到主干 master 中提交了 C9C10,再回到 iss91v2 继续工作,提交 C11,接着,又冒出个不太确定的想法,从 master 的最新提交 C10 处开了个新的分支 dumbidea 做些试验。现在,假定两件事情:我们最终决定使用第二个解决方案,即 iss91v2 中的办法;另外,我们把 dumbidea 分支拿给同事们看了以后,发现它竟然是个天才之作。所以接下来,我们准备抛弃原来的 iss91 分支(实际上会丢弃 C5C6),直接在主干中并入另外两个分支
    分支合并结果
    分支合并结果
  • 特性分支 在任何规模的项目中都可以使用特性分支。一个特性分支是指一个短期的,用来实现单一特性或与其相关工作的分支该技术允许你迅速且完全的进行语境切换,工作将分散在不同的流水线上,每个分支都有特定的目标特性。

操作

创建分支(by Shell)

git branch dev 创建分支dev,无输出

创建分支(by Desktop)

点击branch前的分支按钮 -> 输入 Name -> 选择 From branch -> Create new branch

切换分支(by Shell)

从当前的提交之后创建分支

git checkout dev 切换到分支dev,输出 Switched to branch 'dev'
git checkout -b dev 创建并切换到 dev 分支,输出 Switched to a new branch 'dev'

切换分支(by Desktop)

点击当前分支名称旁的下拉按钮,选择分支

不同分支的内容的可见性(by Shell)

不同的分支管理不同的commit,commit之间通过地址单向访问,继而限制了不同分支的可见性,git checkout branchName 切换到不同分支之后,工作区的文件内容会自动更新。注意备份工作区的修改

查看分支(by Shell)

git branch 查看分支列表

合并分支(by Shell)

dev并入master

  • 切换到 master分支,git checkout master
  • 合并 dev 分支到当前分支,git merge dev

合并分支(by Desktop)

切换到 master -> compare -> 选取待合并的目标分支 -> update from target branch

合并方式
  • Fast-forward,“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快
合并冲突
  • 设想情景,在 commit n 之后创建分支 dev,提交修改 commit n+1,切换到 master 分支,提交修改 commit n+2 ,然后试图将 dev 分支合并到 master时出现冲突,输出 Auto-merging README.md \n CONFLICT (content): Merge conflict in README.md \n Automatic merge failed; fix conflicts and then commit the result.

  • 输出:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

其中,Git用<<<<<<<=======>>>>>>>标记出不同分支的内容。

  • 直接对冲突的文件进行修改,删除不同分支冲突的内容。
  • master分支提交修改。
  • git log --graph --pretty=oneline --abbrev-commit 查看分支的合并情况

删除分支 (by Shell)

git branch -d dev 删除分支 dev

删除分支 (by desktop)

切换到目标分支 -> 右上角齿轮状设置按钮 -> Delete target_branch ...

查看分支合并情况 (by Shell)

git log --graph --pretty=oneline --abbrev-commit 查看分支的合并情况及相应的提交

git 分支管理策略

团队合作分支策略

团队合作的分支策略
团队合作的分支策略
  • 首先,master分支应该非常稳定,仅用来发布新版本,平时不能在上面干活;
  • 干活都在 dev 分支上,即 dev 时不太稳定的,更超前的;
  • 不同的开发人员在不同的分支上进行开发,然后将性能稳定的版本合并至 dev 版本上。

bug分支及当前分支工作的stash储藏功能

  • 情景 软件开发中遇到 bug 时,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。比如当你接到一个修复一个代号101bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,假如当前正在dev上进行的工作还没有提交,并且当前的工作仍在进行中,不能提交,然而创建分支修改bug又势在必行。此时创建分支修改bug后提交修改时,会将dev的内容同时提交。此时需要stash保存工作现场。

操作

创建commit的合并方式 (by Shell)

合并分支时,Git会尽可能采用 Fast forward 模式,在这种模式下,删除分支后,会丢掉分支信息。如果强行禁用 Fast forward 模式,Git就会在 merge 时生成一个新的 commit, 这样分支历史就可以看出分支信息。

工作现场stash的使用 (by Shell)

当工作区的目标不适合提交(正在开发或者是脏的提交)时,使用 stash 保存快照,并进行恢复,不过 stash 只保存改变的需要被跟踪的文件,其他文件不会被跟踪。恢复 stash 时,若跟踪的文件被修改,会遇到冲突。

  • git stash 保存工作现场,此时 git status 查看工作区没有修改信息
  • git stash list 查看工作现场的列表
  • git stash apply stash@{id} 恢复 stash@{id} 的内容, git stash drop 删除工作现场
  • git stash pop stash@{id} 恢复 stash@{id} 的内容同时删除它

git merge --no-ff -m "merge message" dev 合并分支并提交merge信息

强行丢弃分支

git branch -D <name> 可以强行删除未合并到主分支的特性分支

多人协作的工作方式

当有冲突的时候,先用 git pull 把最新的提交从 origin/dev 抓下来,然后在本地合并,解决冲突,再推送

  • 首先,可以试图用git push origin branch-name推送自己的修改;
  • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull抓取远程仓库的最新更新;
  • 如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,指定本地devorigin/dev分支的链接,git branch --set-upstream dev origin/dev
  • 然后本地的仓库中出现冲突,需要手动解决,解决方式与分制管理中的解决冲突的方式一致。解决冲突提交到本地仓库,
  • 推送到远程仓库 git push origin dev

标签管理

tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起,一般给程序的不同版本设置标签,便于快速查找

操作

创建标签 (by Shell)

  • 切换到需要打标签的分支上 git checkout <branch name>
  • 创建标签 git tag <name> 对最新的提交打标签
  • 创建标签 git tag <tag name> <commit id> 给指定提交打标签
  • 创建有说明信息的标签 git tag -a <tagname> -m "tag message" <commit id>

查看所签 (by Shell)

  • 列出所有标签 git tag, 标签的顺序是字母顺序,而不是时间顺序
  • 查看标签的详细信息 git show <tagname>

删除标签 (by Shell)

  • 删除本地仓库标签 git tag -d <tag name>
  • 删除远程仓库的标签, 先删除本地标签 git tag -d <tag name>,然后删除远程的标签 git push origin :refs/tags/v0.9

推送标签到远程仓库 (by Shell)

  • 推送单个标签 git push <branch name> <tag name>
  • 一次性推送多个标签 git push origin --tags
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 1. 安装 Github 查看是否安装git: $ git config --global user.name "...
    Albert_Sun阅读 13,631评论 9 163
  • 奔跑第十五天 “春风化雨暖透我的心,一生眷顾无言的赠送”,生活总是一成不变就显得过于平淡,哪怕是起起落落也是一种很...
    涵涵随记阅读 287评论 0 1
  • 晨登涂山寻禹迹,春入岭峦已葱笼。 寺钟伴茗且得闲,但见大江从容去。
    苦茶及酒阅读 429评论 0 0
  • 早上醒来,习惯性的打开新闻,看看又发生了什么新鲜事。陈思城出轨了,惊愕之余,太心疼丫丫,孩子才两岁,她将如何选择,...
    阳阳小麦阅读 317评论 3 1