程序员

git的学习笔记-入门

2017-04-16  本文已影响178人  呆呆的张先生

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的知识结构

后续学习任务

工作区及版本库的概念

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

什么分支需要推送?

推送本地仓库内容到远程仓库(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

合并分支(by Desktop)

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

合并方式
合并冲突
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用<<<<<<<=======>>>>>>>标记出不同分支的内容。

删除分支 (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 merge --no-ff -m "merge message" dev 合并分支并提交merge信息

强行丢弃分支

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

多人协作的工作方式

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

标签管理

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

操作

创建标签 (by Shell)

查看所签 (by Shell)

删除标签 (by Shell)

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

上一篇下一篇

猜你喜欢

热点阅读