zoukankan      html  css  js  c++  java
  • git入门及使用记录

    前言

    此文用于记录学习git,学自廖雪峰老师的教程,有需要者可看这:Git教程

    Git简介

    1.Git是目前世界上最先进的分布式版本控制系统
    2.CVS和SVN都是集中式的版本控制系统
    3.CVS作为最早的开源而且免费的集中式版本控制系统,直到现在还有不少人在用。由于CVS自身设计的问题,会造成提交文件不完整,版本库莫名其妙损坏的情况。同样是开源而且免费的SVN修正了CVS的一些稳定性问题,是目前用得最多的集中式版本库控制系统。

    初始化一个Git仓库

    首先,先上一张图,方便大家记忆:

    1.初始化一个Git仓库,使用git init命令。
    2.添加文件到Git仓库,分两步:

    • 使用命令git add <file>,注意,可反复多次使用,添加多个文件
    • 使用命令git commit -m <message>,完成。

    3.git status命令可以让我们查看仓库当前的状态
    4.git diff是查看difference,显示的格式是Unix通用的diff格式
    5.git log命令显示从最近到最远的提交日志
    6.关于版本控制:

    • HEAD指向的版本就是当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
    • 因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id即可。
    • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
    • 要重返未来(回退后又后悔了),用git reflog查看命令历史,以便确定要回到未来的哪个版本。

    Git暂存区

    1.Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
    2.关于Git的三个区:

    • 工作区(Working Directory)就是在电脑里能看到的目录(即项目的目录)
    • 暂存区(starge)
    • 仓库分支(master)

    版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

    Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

    3.关于git diffgit diff --cached区别:

    1.git diff比较的是工作目录中当前文件暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容。若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached命令。
    2.请注意,git diff本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。

    经过尝试,理解为:

    • git diff比较的是工作区文件暂存区文件的区别(上次git add的内容)(因为可能有多次git add,每次修改后没有进行git add的内容和上次进行git add的内容进行比较)
    • git diff --cached 比较的是暂存区的文件仓库分支里上次git commit后的内容)的区别

    4.每次修改,如果不用git add到暂存区,那就不会加入到commit中
    5.git checkout -- file可以丢弃工作区的修改,具体运用有:

    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
    场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作。
    场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。

    6.关于删除

    • 先删除文件夹(工作目录)下的文件,然后用git status查看(不是必要的,如果对命令很熟的话)然后根据提示和自己的想法看是真的删除还是撤销。
    • 命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

    远程仓库

    本地仓库的内容推送到GitHub仓库

    1.创建SSH Key

    • 先执行以下语句来判断是否已经存在本地公钥(git中执行): cat ~/.ssh/id_rsa.pub
    • 如果你看到一长串以ssh-rsassh-dsa开头的字符串, 则可以跳过ssh-keygen的步骤。否则 需要用下面的命令来生成ssh key:
      ssh-keygen -t rsa -C "youremail"
    • 这个指令会要求提供一个位置和文件名去存放键值对和密码,可以点击Enter键去使用默认值。
    • 用以下命令获取生成的公钥:
      cat ~/.ssh/id_rsa.pub或者在用户主目录的.ssh文件夹中找到,一般在C:UsersAdministrator

    2.在github上创建仓库(这是在本地已经存在仓库的情况下,不可以勾选Initialize this repository with a README,不然会出现很多错误。这样可以立即克隆这个仓库到自己电脑,但这不是我们需要的)如果本地无相应仓库,则可以勾选(下面说)。

    3.根据提示,使用git remote add origin git@server-name:path/repo-name.git;关联远程库,然后使用git push -u origin master把本地库的所有内容推送到远程库上

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

    4.此后,只要本地作了提交,可直接用git push origin master把本地master分支的最新修改推送至GitHub,现在,就拥有了真正的分布式版本库。

    5.总结:

    • 要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;
    • 关联后,使用命令git push -u origin master第一次推送master分支的所有内容
    • 此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改

    从远程库克隆

    1.在github上创建仓库时,勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。
    2.克隆即可:使用git clone git@server-name:path/repo-name.git;(git@开始都是直接复制即可)这样便克隆到了本地库(多个人协作开发,那么每个人各自从远程克隆一份就可以了)
    3.Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。

    分支管理

    使用分支:

    1.查看分支:git branch

    2.创建分支:git branch <name>
    切换分支:git checkout <name>
    或直接
    创建+切换分支:git checkout -b <name>

    3.合并某分支到当前分支:git merge <name>

    4.删除分支:git branch -d <name>

    解决冲突

    1.当Git无法自动合并分支时(比如同时在两个分支上做了修改并都已经commit),就必须首先解决突。解决冲突后,再提交,合并完成。

    2.解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。

    3.用git log --graph命令可以看到分支合并图。

    4.合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

    5.命令一般为:git merge --no-ff -m "about information" dev因为合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

    Bug分支

    1.修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除
    2.当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。
    3.回到现场也可以用git stash apply恢复,但是恢复后,stash内容并不删除,还需要用git stash drop来删除

    Feature分支

    1.每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

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

    多人协作

    1.多人协作的工作模式通常是这样:

    • 首先,可以试图用git push origin <branch-name>推送自己的修改;
    • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
    • 如果合并有冲突,则解决冲突,并在本地提交;
    • 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
    • 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>(出错会有提示)

    2.小结

    • 查看远程库信息,使用git remote -v
    • 本地新建的分支如果不推送到远程,对其他人就是不可见的;
    • 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
    • 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
    • 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name
    • 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

    3.分支

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

    Rebase

    1.rebase操作可以把本地未push的分叉提交历史整理成直线;

    2.rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

    3.关于原理,可参考这篇文章:Git Community Book 中文版

    4.文中的例子:
    执行(mywork和origin分别为两个分支)

    $ git checkout mywork
    $ git rebase origin
    

    这些命令会把你的"mywork"分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到".git/rebase"目录中), 然后把"mywork"分支更新到最新的"origin"分支,最后把保存的这些补丁应用到"mywork"分支上。

    5.在rebase的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止rebase并会让你去解决 冲突;在解决完冲突后,用git add命令去更新这些内容的索引(index), 然后,你无需执行 git commit,只要执行:git rebase --continue这样git会继续应用(apply)余下的补丁。

    6.在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。

    简而言之,就是把mywork分支提交先撤销,然后指向到最新节点,然后再提交(如果有冲突,需要手动处理,用git add命令去更新这些内容的索引(index), 然后执行:git rebase --continue这样git会继续应用(apply)余下的补丁)

    标签管理

    1.创建标签

    • 命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
    • 命令git tag -a <tagname> -m "blablabla..."可以指定标签信息,-a指定标签名,-m指定说明文字
    • 命令git tag可以查看所有标签。用命令git show <tagname>可以看到对应的说明文字

    2.命令git push origin <tagname>可以推送一个本地标签;

    3.命令git push origin --tags可以推送全部未推送过的本地标签;

    4.命令git tag -d <tagname>可以删除一个本地标签;

    5.命令git push origin :refs/tags/<tagname>可以删除一个远程标签(得先删除本地对应标签)

    自定义Git

    让Git显示颜色

    让命令输出看起来更醒目,使用:git config --global color.ui true

    忽略文件

    1.忽略某些文件时,需要编写.gitignore。在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。

    2.所有配置文件可以直接在线浏览:gitignore 找到自己需要的加入即可。

    3.忽略文件的原则是:

    • 忽略操作系统自动生成的文件,比如缩略图等
    • 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件
    • 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

    4.可以用-f强制添加到Git,如git add -f App.class

    5.若觉得规则写错了,可以用git check-ignore命令检查。或者直接打开.gitignore文件检查。

    配置别名

    1.使用alias设置别名,如git config --global alias.st status

    2.一些常用别名设置

    git config --global alias.st status
    git config --global alias.co checkout
    git config --global alias.ci commit
    git config --global alias.br branch
    git config --global alias.unstage 'reset HEAD'
    git config --global alias.last 'log -1'
    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"
    
    

    3.使用git config --global --list查看用户的配置信息,若想看当前仓库的,用git config --local --list

    3.配置文件

    • 配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
    • 每个仓库的Git配置文件都放在.git/config文件中
    • 当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig
    感谢阅读,如有问题,请批评指正,谢谢。
  • 相关阅读:
    【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game
    【二分】【三分】【计算几何】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem L. Lines and Polygon
    【线段树】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem J. Jedi Training
    【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word
    【转载】随机生成k个范围为1-n的随机数,其中有多少个不同的随机数?
    【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring
    【枚举】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem D. Cutting Potatoes
    【找规律】【递归】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem F. Doubling
    【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!
    【计算几何】【圆反演】计蒜客17314 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 G. Finding the Radius for an Inserted Circle
  • 原文地址:https://www.cnblogs.com/clwsec/p/12503278.html
Copyright © 2011-2022 走看看