Git学习笔记

1 版本库与文件操作#  

1.1 创建版本库(初始化版本库)

  ​ 首先在GitBash中cd到要创建仓库的位置(或者直接进入相应目录,点鼠标右键然后选择Git Bash Here),执行git init,仓库创建成功后会在仓库文件夹中生成(.git目录),这个目录是隐藏目录,在window中查看时需要显示隐藏文件;在linux中则加 -a 参数,这个目录是Git来跟踪管理版本库的 ,千万不要手贱修改。我们创建Git版本库时,Git会自动为我们创建唯一一个master分支 .

1.2 添加文件到Git仓库  

  1.  git add <fileName> ,将文件放进暂存区(stage) ,此命令可反复多次使用,也可同时添加多个文件;
  2. 使用命令 git commit -m <message> ,添加到版本库 ,即把暂存区的所有内容提交到当前分支 ,其中message是本次提交的描述;

1.2.1 查看仓库状态​

  git status 命令可以随时掌握工作区的状态 ,此命令的几种结果如下(加参数-s表示简短输出;熟练了可使用这个参数):

    1. Changes not staged for commit:文件更改了,但是还未进入暂存区 ,需要add;
    2. Changes to be committed:文件已进入暂存区,但还未提交到版本库,需要commit ;
    3. Untracked files:表示该文件还从来没有被添加进版本库;

1.2.2 查看修改内容  

  如果  git commit -m <message>  告诉你有文件被修改过,用  git diff  可以查看修改内容,语法为:  git diff <fileName>  ,add文件之前最好看一下。

1.2.3 提交已修改  

   提交到本地库后的文件在工作区再次被修改了,可以使用add先添加到暂存区,也可以直接使用commit提交到本地库(直接提交的前提是该文件之前被提交到本地库中了,即新建的文件不能直接提交),直接提交是一样的两步 :先add和再commit;只是git默认做了add这一步。

  

1.3 版本回退  

  每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为  commit  。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个  commit  恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

  1.   git log   可以查看提交历史 (即查看版本库的状态 ),显示从最近到最远的提交日志;  git log --pretty=oneline   使每个日志单独成行(简化版输出)。

  2. git中,用  HEAD  表示当前版本(版本的索引)。 

  3. git reflog  查看所有命令历史;

  4. 回退到上一个版本:  git reset --hard HEAD^ HEAD^表示回退1个版本, HEAD^^表示回退2个版本,几个^退几个版本;HEAD~100 表示回退100个版本。HEAD其实是个指针。  

  5. 通过索引去到指定的版本:  git reset --hard 版本的索引  。其中“版本的索引”的可以通过git reflog等命令获取,Git会自动去找。

    reset的三个参数对比:

      --hard:1、在本地库移动HEAD指针  2、重置暂存区  3、重置工作区

      --mixed:1、在本地库移动HEAD指针  2、重置暂存区

      --soft:1、仅仅移动本地库HEAD指针

1.4 工作区和暂存区  

  工作区:就是当前的工作目录。版本库:工作区里面隐藏的 .git 目录就是Git的版本库。

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

  git add + git commit:可以理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。 如图:

 

  注:Git跟踪并管理的是修改,而非文件。 每次修改,如果不 git add 到暂存区,那就不会加入到 commit 中。

1.5 撤销修改,撤销删除  

  场景1. 当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git restore <file>

若文件自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
若文件已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

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

1.6 比较文件

  git diff <filename>  : 工作区与暂存区的比较(不指定filename时则所有文件都进行比较)

  git diff HEAD <filename>  : 工作区与本地库的比较(当然HEAD也可以替换为HEAD^或者HEAD~20或者本地库版本号)

1.7 删除文件  

  删除工作区中的文件: rm <fileName>  

  删除本地库中的文件:git rm <fileName> 

2 远程仓库  

  Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。 每个人都从“服务器”仓库上克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。

  github的首页就是注册登录页

2.1 创建远程库

 

2.2 克隆

  选取自己的计算机中的一个路径,执行clone命令

  git clone [远程地址] 执行完之后就会把远程库下载到本地,并初始化本地库

  远程地址如图下:

  

2.3 创建远程库地址别名

  git remote -v    查看当前所有远程地址别名

  git remote add [别名] [远程地址]    添加远程库别名

2.4 推送

  git push [别名]  [分支名]    当然也可以不用别名,用远程地址也行

  在windows10(其它操作系统还未了解)中第一次push时在git中需要登录,之后windows会默认保存这个用户,若之后想切换用户需要删除windows10保存的这个用户

  

2.5 团队成员邀请

   

   然后输入所要邀请成员的用户名或邮箱进行邀请即可

  

2.6 拉取

  • pull=fetch+merge

   git fetch [远程库地址别名] [远程分支名]

   git merge [远程库地址别名/远程分支名]

   git pull [远程库地址别名] [远程分支名]

2.7 解决push冲突

  要点

    如果不是基于 GitHub 远程库的最新版所做的修改,不能推送,必须先拉取。

    拉取下来后如果进入冲突状态,则按照“分支冲突解决”操作解决即可。

2.8 跨团队合作

  举例:

    跨团队合作的意义:岳不群在一个公司;东方不败在另一个公司;此时东方不败不能说跳槽去岳不群团队帮他干活,此时岳不群又想东方不败帮忙,此时就需要用到跨团队合作

    1、岳不群创建了一个huashan项目在他的远程库中

    2、此时东方不败进入岳不群的这个项目中进行fork操作

     

      点击之后稍等片刻

      

     3、在东方不败的远程库中可以看到fork项目成功

      

    4、东方不败在本地进行修改,然后推送到自己的远程库

      5、东方不败再发出 Pull request;让岳不群进行同意拉取合并

       

         

         

          

    6、岳不群进入自己的远程库,查看pull request 请求

      

     7、查看东方不败发来的pull request

      

    8、进入之后可以进行对话

    

      

    9、代码审核

    

   10、合并代码

    

      

   11、岳不群再拉取到本地库操作

2.9 SSH免密登录

   1、进入当前用户的家目录:cd ~

   2、删除.ssh 目录:rm -rvf .ssh

  3、运行命令生成.ssh 密钥目录:ssh-keygen -t rsa -C [github用户的邮箱]     [注意:这里-C 这个参数是大写的 C]

  4、进入.ssh 目录查看文件列表:先cd .ssh  然后ls -lF

  5、查看 id_rsa.pub 文件内容:cat id_rsa.pub

  6、复制 id_rsa.pub 文件内容,登录 GitHub,点击用户头像→Settings→SSH and GPG keys→New SSH Key

  

  7、输入复制的密钥信息到key中,title随便取个名字

  

  8、回到 Git bash 创建远程地址别名(此时加的是ssh方式的远程地址,不是http的了):git remote add origin_ssh [ssh方式的远程项目地址]

    

  9、推送文件进行测试      

3 分支管理  

  如果你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

3.1 分支与管理  

  严格来说 HEAD 并不是指向提交,而是指向 master master 才是指向提交的,所以,HEAD指向的就是当前分支。 这部分还是推荐看下[廖雪峰][https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840038939c291467cc7c747b1810aab2fb8863508000]官网的图,更易理解。

  1. 查看分支: git branch  

  2. 创建分支(相当于增加了一个dev指针): git branch [分支名]  ,切换分支: git checkout [分支名]

  3. 创建+切换分支:git checkout -b [分支名] 

  4. 合并某分支到当前分支: git merge [分支名] 

  5. 删除分支: git branch -d [分支名]  

3.2 合并分支时解决冲突 

  合并分支时就可能出现代码冲突,任何合并冲突都必须人去解决。人生不如意之事十之八九,合并分支往往也不是一帆风顺的。

  其实冲突的本质是:不同的分支修改了代码相同的部分,从而导致合并分支时出现冲突(虽然冲突,但还是会合并,会自动标注出冲突的地方)。所以解决冲突就需要我们把Git合并失败的文件进行手动修复,改为我们想要的内容再提交(add + commit)即可,解决冲突时commit的时候不需要加文件名

 

 

  可以用带参数的  git log  查看分支的合并情况(分支历史): git log --graph --pretty=oneline --abbrev-commit  

3.3 分支管理策略  

  合并分支时,默认采取的为  Fast farword  模式,这种合并看不到合并历史,删除分支会丢掉分支信息。

  禁用  Fast farword  模式时,合并分支时会产生一个新的  commit  ,这样,从分支历史上就可以看出分支信息。 用  git merge --no-ff -m "merge with no-ff" dev 命令合并,其中,--no-ff参数,表示禁用Fast forward模式。 因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

$ git log --graph --pretty=oneline --abbrev-commit // 查看分支历史
* e1e9c68 (HEAD -> master) merge with no-ff
|\ 
| * f52c633 (dev) add merge //可以看到用--no-ff参数,合并分支时会新创建一次提交
|/ 
* cf810e4 conflict fixed
...

  可以看到,不使用Fast forward模式,merge后就像这样 :

 

分支策略(分支管理)图如下:

 

3.4 Bug分支  

  修复bug,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

假设场景是这样的:A为正在开发的软件

  1、假设master分支上面发布的是A的1.0版本,dev分支上开发的是A的2.0版本
  2、若这时用户反映 1.0版本存在漏洞,则需要从dev切换到master去修复漏洞, 这时按理应该先提交在dev分支上的工作,然后从dev分支切换到master分支去修复漏洞,但这时你在dev分支上的工作只进行了一半,还没法提交。
  3、此时可以用git stash命令来把当前工作现场(dev分支)“储藏”起来,等以后恢复现场后继续工作。
  4、切换到master分支,在master分支建立issue-101分支,切换到issue-101分支修复漏洞,修复完成后提交,然后切换到master分支上合并issue-101分支git merge --no-ff -m "merged bug fix 101" issue-101。
  5、切换回dev分支,,git stash list命令看看stash内容,然后git stash pop,恢复的同时把stash内容也删了继续工作。
注:恢复工作现场的两种方式

  1.是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除; (你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash )。
  2.用git stash pop,恢复的同时把stash内容也删了 。

3.5 强制删除  

  开发一个新feature,最好新建一个分支; 如果要丢弃一个没有被合并过的分支(已提交),可以通过git branch -D <name>强行删除。

3.6 多人协作 

  因本部分比较重要,所以整理得比较详细,内容略多。

  当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin,用git remotegit remote -v可查看远程库的信息。

3.6.1 推送分支  

  一般来说,master主分支和dev开发分支,都要时刻与远程库保持同步,所以需要推送。其他分支,比如bug分支和feature分支等,是否需要推动到远程可依具体情况而定。

// 推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上
git push origin master 
git push origin dev

3.6.2 抓取分支  

  其他小伙伴用git clone https://github.com/ft-sunshine/learningGit.git从远程库克隆,默认只会克隆master分支,可用git branch查看。若小伙伴也要在dev分支上开发,则必须创建远程origindev分支到本地,用git checkout -b dev origin/dev。完成相关工作后,时不时地把dev分支push到远程,用git push origin dev

  若你的小伙伴对dev分支的某个文件做了修改,并且push了dev分支,而碰巧你也对同样的文件作了修改,并试图推送 git push origin dev,这时会推送失败(出现冲突)。此时应先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送 。

  这时若直接用git pull会失败,因为到目前为止还没有指定本地dev分支与远程origin/dev分支的链接,应设置devorigin/dev的链接: git branch --set-upstream-to=origin/dev dev,然后再git pull就成功了。但这时合并会有冲突,需要手动解决,解决后提交,再git push origin dev即可。

3.6.3 多人协作的工作模式

  因此,多人协作的工作模式通常是这样:

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

  这就是多人协作的工作模式,一旦熟悉了,就非常简单。

3.6.4 小结

  ● 查看远程库信息,使用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,如果有冲突,要先处理冲突


问题:A:push 文件1.txt B:push 文件1.txt(显然冲突),所以先pull,然后手工合并,假如合并过程中,A又push 文件1.txt了。等B合并完,push 文件1.txt时,又冲突掉了。感觉这情况很影响工作效率,请问git是否有对这情况有处理机制的?(SVN是有“锁”这概念的)。

答:无解,找A吵一架,所以说共同开发时,合作很重要!

4 标签管理  

  Git的标签是版本库的快照,它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动)。总之,tag就是一个让人容易记住的有意义的名字(相比于commit id来说),它跟某个commit绑在一起。

4.1 创建标签  

  首先,切换到需要打标签的分支上:

  命令git tag <tagname> [commit id]用于新建一个标签,默认标签是打在最新提交的commit上的,也可以指定一个commit id(找到历史提交的commit id:git log --pretty=oneline --abbrev-commit);
  命令git tag -a <tagname> -m "describe" [commit id]可以指定标签信息;
  命令git tag可以查看所有标签。
  可以用git show <tagname>查看标签信息,
注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

4.2 操作标签  

  默认创建的标签都只存储在本地,不会自动推送到远程,所以,打错的标签可以在本地安全删除。 。

  命令git push origin <tagname>可以推送一个本地标签到远程库;
  命令git push origin --tags可以推送全部未推送过的本地标签到远程库;
  命令git tag -d <tagname>可以删除一个本地标签;
  命令git push origin :refs/tags/<tagname>可以删除一个远程标签(先从本地删除)。

5 使用码云  

  国内的Git托管服务—码云,码云也提供免费的Git仓库,5人以下小团队免费。码云的基本操作和GitHub的操作一致。

  把本地库关联到远程库:(假设已经有了一个本地库叫“learngit ”)

  1、首先,在码云上创建一个新的项目,项目名称最好与本地库保持一致 。

  2、然后,我们在本地库上使用命令git remote add <URL>把它和码云的远程库关联。若这时出现远程库origin已存在的错误,则应该先删除远程库:git remote rm origin

  3、这时载再关联码云的远程库即可成功,可用git remote -v查看,这时就可以通过git push命令把本地库推送到Gitee上。

  4、一个本地库能既关联GitHub,又关联码云(注:git给远程库起的默认名称是origin) :

    1.先删除已关联的名为origin的远程库:git remote rm origin

    2.git remote add github git@github.com:michaelliao/learngit.git

    3.git remote add gitee git@gitee.com:liaoxuefeng/learngit.git  注意此时远程库的名称叫gitee,不叫origin ,可用git remote -v查看。

    4.此时推送的命令变为:git push github mastergit push gitee master

 

常见问题及解决办法

  每次push,pull都需要密码

// 这个命令则是在你的本地生成一个账号密码的本子似的东东,这样就不用每次都输入了(但是还得输入一次)

git config --global credential.helper store

// 这个指令对于windows,linux都是通用的,可以通过以下命令查看

cat ~/.git-credentials

 

 

摘自https://blog.csdn.net/ft_sunshine/article/details/87010772

posted @ 2020-03-30 16:49  Arbitrary233  阅读(239)  评论(0编辑  收藏  举报