学习笔记——Git

来源:互联网 发布:python 2.7 pyqt4下载 编辑:程序博客网 时间:2024/05/11 03:48

欢迎访问 博客新址

  • 说明,此博文是学习《Git教程——廖雪峰》的笔记

一、安装和设置

# Ubuntu安装Gitsudo apt-get install git -y# 设置全局用户名和邮件,该机器上所有仓库使用该配置$ git config --global user.name "Your Name"$ git config --global user.email "email@example.com"

二、创建版本库

创建版本库

# 创建一个空目录mkdir learngitcd learngitpwd# 将目录变成“Git仓库”git init
  • 该Git库是空仓库。不要私自修改.git目录,Git用它来跟踪管理版本库。
  • 不是必须在空目录下创建Git仓库。
  • 所有的版本控制系统,其实只能跟踪文本文件的改动,Git也是如此。对于图片和视频等二进制文件,可以使用Git管理,但没法跟踪文件的变化。

添加和提交文件

  • 创建readme.txt,添加如下内容。
Git is a version control system.Git is free software.
  • 使用下面的命令添加和提交文件:
# 添加到仓库git add readme.txt# 提交到仓库git commit –m “wrote a readme file”
  • -m “….”是注释,便于查找改动。推荐使用。
  • git commit 相当于保存一个快照,可以用于恢复。
  • 为什么Git添加文件需要add、commit两步?因为commit可以一次提交很多文件。
# 多次add,一次提交git add file1.txtgit add file2.txt file3.txtgit commit –m “add 3 file.”

查看仓库状态和文件变化

  • 要随时掌握工作区的状态,使用git status命令。
  • 如果git status告诉你有文件被修改过,使用git diff查看修改内容。
  • 修改readme.txt,如下所示。
Git is a distributed version control system.Git is free software.
  • 输入以下命令练习。
# 掌握仓库的当前状态git status #红色# 查看修改内容# git diff的显示格式是Unix通用的diff格式git diff readme.txt# 添加到仓库git status #绿色# 提交到仓库git commit -m “add distributed”git status

三、时光穿梭机

版本回退

  • git log 显示提交日志(从最近到最远)
  • git log –pretty=online 精简显示
  • git reset 版本回退
  • 类似0347cda67cf047da1ad612ab2319e2ef2bf8cff8commit id(版本号)。之所以不用1,2…,是为了防止多人在同一个仓库工作时出现冲突。
  • Git把每次提交串成一条时间线。
  • 在Git中,用HEAD表示当前版本,也就是最新的提交。上一个版本就是HEAD^,上上一个版本就是HEAD^^,往上100个版本就是HEAD~100。
  • 只要记得版本号,回退之后还可以恢复。(命令行窗口未关或提前保存了git log)
  • Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向当前版本,改为指向上一个版本。
  • 让HEAD指向哪个版本号,你就把当前版本定位在哪。
  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset –hard commit_id。
  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

修改readme.txt,如下所示。

Git is a distributed version control system.Git is free software distributed under the GPL.

输入以下命令练习。

# 提交git add readme.txtgit commit –m “append GPL”# 查看提交日志git log# 保存提交日志git log > ../log.txt# 精简显示日志git log –pretty=oneline# 回退到上个版本git reset –hard HEAD^# 查看提交日志(最新的已经没有了)git log# 恢复最新版本(前提:命令行窗口未关)# 查看最新版本的版本号。假定为: 73bdb9efc29b3ed95567e57e4640418e8e809307git reset –hard 73bdb9efc# 如果命令行窗口已关,通过git reflog命令查看历史命令(包含版本号)git reflog

工作区和暂存区

  • Git区别于其它版本控制器之处在于:Git有暂存区。
  • 工作区:在电脑里能看到的目录。
  • 版本库:工作区中的隐藏目录.git。
  • 版本库中有:暂存区(stage或index),master分支,以及指向master的指针HEAD。
    这里写图片描述
  • 提交文件到Git仓库分为2步:git add是把文件修改添加到暂存区;git commit是把暂存区的所有内容提交到当前分支。
  • master分支是创建Git版本库时,Git自动创建的。
  • 简单理解:需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改到当前分支。

修改readme.txt,如下所示。

Git is a distributed version control system.Git is free software distributed under the GPL.Git has a mutable index called stage.
  • 在工作区新增文件LICENSE,内容随便。

执行以下命令,检查状态和添加文件。

git statusgit add readme.txtgit add LICENSEgit status
  • 暂存区的状态如下图所示。
    这里写图片描述
  • git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。
git commit -m “understand how stage works”git stauts

这里写图片描述
* 暂存区是Git非常重要的概念,弄明白了暂存区,就弄明白了Git的很多操作到底干了什么。

管理修改

  • Git比其它版本控制系统优秀的地方在于:GTI跟踪并管理修改,而非文件。
  • 下面的例子说明了这个过程。
# 修改readme.txtgit add readme.txtgit status# 继续修改git commit -m “git tracks changes”git status#说明:第一次修改提交了,第二次修改没有提交# 检查工作区和版本库里最新版的区别git diff HEAD -- readme.txt
  • Git跟踪修改原理:每次修改,如果不add到暂存区,那就不会加入到commit中。

撤销修改

  • git checkout – filename
  • git checkout – readme.txt 就是把readme.txt文件在工作区的修改全部撤销。分两种情况:第一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;第二种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。总之,就是让这个文件回到最近一次git commit或git add时的状态。
  • 如果想删除已经git add,但是没有git commit的内容。就使用git reset HEAD readme.txt命令。git reset HEAD filename 可以把暂存的修改撤销掉,重新放回工作区。
  • git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。
  • 如果已经git commit,但是没有把自己的本地库推送到远程。可以通过git reset实现版本回退。
  • 如果已经推送到远程,就没有办法删除了。

删除文件

  • 真的删除文件
rm test.txtgit rm test.txtgit commit -m “remove test.txt”
  • 误删文件,恢复到最新版
rm test.txt# 发现删错了,恢复git checkout -- tes.txt
  • 命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

三、远程仓库

  • Git杀手级功能:远程仓库。Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。
  • 最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。
  • 实际情况:找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
  • Github,提供了Git仓库托管服务。国内有类似的coding。
  • 本地Git仓库和GitHub仓库之间的传输是通过SSH加密的。
  • 配置:

    • 第1步:创建SSH Key。

      # 创建SSH Keyssh-keygen -t rsassh-keygen -t rsa -C “youremail@example.com” #~/.ssh目录下生成两个文件:id_rsa(私匙)和id_rsa.pub(公匙)
    • 第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面;然后,点“Bew SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容

  • 为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的。
  • Github上的免费托管的Git仓库是公开的,别人可以看到。国内的coding.net可以免费托管私有仓库。

添加远程仓库

  • 在Github上创建一个远程库,可以克隆这个库,或者和本地的仓库进行合并。
    • 在Github上创建远程库learngit;
    • 上传自己的SSH公匙;
    • 关联本地仓库和远程仓库。
    • 推送代码
#关联远程库git remote add origin git@github.com:xuezhisd/learngit.git#关联后,远程库的名字就是origin# 推送本地库内容到远程库上git push -u origin master# -u把本地的master分支和远程的master分支关联起来,简化以后推送命令。# 以后使用下面命令推送git push orgin master
  • 本地库的内容推送到远程,用git push命令。

从远程库克隆

  • 要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
    Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
git clone git@github.com:xuezhisd/learngit.gitgit clone https://github.com/xuezhisd/learngit.gitcd learngitls

分支管理

  • 分支==平行宇宙
  • 通过创建自己的分支,既可以随时提交,又能避免丢失每天进度的风险。直到开发完成后,在一次性合并到原来的分支上。既安全,有不影响别人工作。
  • Git分支优点:无论创建、切换和删除分支,1秒完成。

创建于合并分支

  • 每次提交串起来,就是一个分支。Git中的master分支是主分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
  • Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:
    这里写图片描述
  • 创建dev分支,并把HEAD指向dev:
    这里写图片描述
  • dev上的工作完成了,就可以把dev合并到master上:
    这里写图片描述
  • 合并完分支后,可以删除dev分支。删除dev分支就是把dev指针给删掉:
    这里写图片描述
# 创建dev分支,然后切换到dev分支# -b表示创建并切换分支git checkout -b dev# 查看当前分支git branch# 修改readme.txt# 提交git add readme.txtgit commit -m “branch test”# 切回master分支git checkout master# 将dev分支的工作合并到master分支# 注意:当前在master分支中git merge dev# 删除dev分支git branch -d dev# 查看剩余分支git branch
  • git merge命令用于合并指定分支到当前分支。

解决冲突

  • 当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
  • 用git log –graph命令可以看到分支合并图。
# 添加分支git checkout -b feature1#readme.txt最后一行添加#Creating a new branch is quick AND simple#提交git add readme.txtgit commit -m “AND simple”#切回mastergit checkout master#readme.txt最后一行添加#Creating a new branch is quick & simple.gti add readme.txtgit commit -m “& simple”# 此时,master分支和feature1分支各自有了新的提交。此时,快速合并无法执行# 尝试合并git merge feature1git status# 查看冲突内容,修改为# Creating a new branch is quick and simple.# 重新提交git add readme.txtgit commit -m “conflict fixed”# 查看分支合并情况git log --graph --pretty-oneline --abbrev-commit# 删除feature1分支git branch -d feature1 

分支管理策略

  • 分支管理的几个基本原则:
    • master分支应该是稳定的,仅用于发布新版本,不用来干活;
    • 平时大家都在dev分支上干活。发布新版本时,再合并到master分支上。
  • 强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
# 创建并切换dev分支git checkout -b dev# 随便修改readme.txt文件# 提交git add readme.txtgit commit -m “add merge”# 切回master分支# 合并dev分支# --no-ff参数:表示禁用Fast forwardgit merge --no-ff -m “merge with no-ff” dev# 查看分支历史git log --graph --pretty=oneline --abbrev-commit
  • Git分支十分强大,在团队开发中应该充分应用。
  • 合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

Bug分支

  • 鉴于Git的分支如此强大,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
  • 先将正在工作现场“储藏”起来,等修复完Bug之后,再恢复现场,继续工作。
  • git stash 把当前工作现场“储藏”起来,等以后恢复现场后继续工作。
# 保存工作现场git stash# 查看工作区,就是干净的,可以放心创建分支修复Bug# 假定需从master分支上修复,就从master创建临时分支# 切回master分支git checkout master# 创建并切到issue-101分支(Bug分支)git checkout -b issue-101# 修改Bug# 提交git add readme.txtgit commit -m “fix bug 101# 切回master分支,合并git checkout mastergit merge --no-ff -m “merged bug fix 101” issue-101# 删除Bug分支git branch -d issue-101# 切回dev分支git checkout dev# 查看装填,此时是干净的git status# 查看工作现场(此时工作现场存在)git stash list# 恢复现场,并删除stash内容git stash pop# 查看工作现场(此时无stash内容了)git stash list
  • 修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
  • 当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

Feature分支

  • 每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
# 为Vulan功能创建并切换分支git checkout -b feature-vulcan#开发功能#开发完毕,提交git add vulcan.pygit statusgit commit -m “add feature vulcan”# 切回dev分支git checkout dev#因某些状况,新功能取消,就地销毁该分支git branch -D feature-vulcan
  • 开发一个新feature,最好新建一个分支;
  • 如果要丢弃一个没有被合并过的分支,可以通过git branch -D 强行删除。

多人协作

  • 从远程仓库克隆时,Git自动把本地的master分支和远程的master分支对应起来,并且,远程仓库的默认名称是origin。
  • 推送分支
# 查看远程库信息git remote# 查看更详细的远程库信息git remote -v# 推送master分支到远程库mastergit push origin master# 推送dev分支到远程库devgit push origin dev
  • 抓取分支
# 克隆远程库git clone git@github.com:xuezhisd/learngit.git# 从远程库克隆时,默认只有master分支# 查看分支git branch#在dev分支上开发,就必须创建远程origin的dev分支到本地git checkout -b dev origin/dev# 多人协作时,可能同时修改了dev分支中的同一文件,这时就会推送失败# 此时需要先抓取分支# 地dev分支与远程origin/dev分支的链接git branch --set-upstream dev origin/devgit pull# 有冲突,需要手动解决,再push

四、标签管理

  • 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。标签也是版本库的一个快照。
  • Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像,但是分支可以移动,标签不能移动)。
  • tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
  • tag如下图所示:
    这里写图片描述

创建标签

  • 首先,切到需要打标签的分支上:
# 查看分支情况git branch# 切换git checkout master
  • 然后,使用命令git tag name打标签:
git tag v1.0
  • 查看所有的标签:
git tag
  • 默认标签是打在最新提交的commit上。如果想给历史commit打标签,需要先找到它的commit id,然后打标签:
# 查找标签git log --pretty=oneline -abbrev-commit# 为历史提交打标签# 加入想打标签的commit id是6224937git tag v0.9 62249# 查看所有标签# 注:标签按字母顺序列出git tag# 查看标签信息git show v0.9
  • 创建带注释的标签:
# 创建带注释的标签git tag -a v0.1 -m "version 0.1 released" 3628164# 查看标签信息git show v0.1
  • 使用PGP私匙签名打标签:
# -m 用私匙签名一个标签fec145a是commit idgit tag -s -m "signed version 0.2 released" fec145a# 查看PGP签名信息git show v0.2

操作标签

  • 标签打错了,删除标签:
git tag -d v0.1
  • 创建的标签只存储在本地,不会自动推送到远程。
  • 将某个标签推送到远程:
# 推送v1.0标签git push origin v1.0# 推送所有标签(为上传的)git push origin --tags
  • 删除远程标签
# 先删除本地标签git tag -d v0.9# 再从远程删除git push origin :refs/tags/v0.9

五、参考

  • Git教程——廖雪峰
0 0
原创粉丝点击