Git訓練場-落花有意隨流水 流水無心戀落花
解决冲突第一步:删除冲突部分首先打开冲突文件ProgramAfile1.txt,可以看到典型的冲突文件显示方式箭头<<<与>>>范围内表示的是发生冲突的位置,B是程序员B对ProgramAfile1.txt所做的修改,A为程序员A和远程仓库C中ProgramAfile1.txt的内容假如这时候AB两位程序员经过了协商,绝对保留B所做的修改,则需要删除其余多余的行注:vim指令补充:通过esc进入命令行模式,双击d单独删除某行,dG删除光标所在行以及其下所有行的内容第二步:进行提交再次查看一下状态发现文件处于工作区,git提醒我们要使用git add指令将已经解决冲突的文件提交到暂存区紧跟着提醒你执行git commit,我们照做执行git commit,然后git自动生成了一个commit信息文件,保存即可,再查看一下状态,即解决冲突这时候我们git commit时候,再git status时显示已经解决冲突,也显示出你比远程的origin/master多了2次提交解密为何快2个版本我们先对比下两个仓库的版本号看看可以看出现在AC两个的仓库仍然是一样的B第一次比AC快是因为B自己对文件进行了修改与提交,所以比AC更快1个版本然后B想push,但因为与C发生冲突,为了解决冲突,所以修改并提交了冲突文件,所以又快了1个版本图文讲解首先A在本地仓库修改了ProgramAfile1.txt,并进行了push到了C此时B同样也在本地仓库进行了一次提交修改ProgramAfile1.txt,但因为修改的是与A同一个文件的同一个地方,所以push失败,只能进行pull到B本地进行手动修改当B执行pull操作时,将远程仓库拉取到本地后,由于发生冲突,所以暂时不会将origin/master的指向更新到最新提交,随后,在B中手动解决冲突并合并后,B的状态变为可以看到解决冲突,手动合并后,B已经往前更新了两次提交,而此时的origin/master仍然指向提交1st我们试试B仓库执行git push发现push成功,并且BC已经相同了我们看看A试试这时候A则慢了BC两个版本三个仓库状态图如下:在实际开发当中,难免会出现多个人修改了同一个文件的情况,在进行手动合并的过程中一定要与对方协商应该如何合并,如何舍取,而不是直接覆盖
Github仓库的创建我们想要在全球最大的同性交流网站上提交你自己本地的版本仓库,那么首先就需要注册一个Gtihub账号,具体的操作无非就是邮箱注册这些,为了方便演示,我初始化了我本地的版本仓库,并创建了一个FirstfileThis is the first line and commitSEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile (master) $ git status On branch master nothing to commit, working tree clean这时候我们进入github的页面中Create a new repository创建新的仓库这个界面因为我选择的是免费的github,所以只能使用Public仓库README我自己写,所以不需要添加,这个仓库我只用作测试与演示,所以不需要添加语言备注.gitignore与license这样我的一个新的仓库就创建好了因为我并没有配置README这个Markdown,所以我要在自己的本地版本仓库配置一个README文档，并提交到我的本地缓存区SEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile (master) $ vim README.md## This repository is used for my Git and Github learning # author * YQHP-YuKiSEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile (master) $ git status On branch master nothing to commit, working tree clean这时候我们就需要将此时的本地版本仓库提交到Github的仓库,我们就可以用到此条命令:git remote add origin意思就将你本地的仓库关联到远程仓库的地址,后面加上你远程仓库的HTTPS$ git remote add origin https://github.com/YQHP-YuKi/Gitleaning.git然后再加上此命令:git push -u origin master这条命令意思就是将本机上的master分支推送到远程版本仓库并与之相关联$ git push -u origin master Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 12 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 583 bytes | 583.00 KiB/s, done. Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/YQHP-YuKi/Gitleaning.git * [new branch] master -> master Branch 'master' set up to track remote branch 'master' from 'origin'.输入你的Github账号密码即可这时候我再刷新我的Github的仓库网页,就看见将本地master传上去了Git远程操作我们在本地Git执行一些命令,可以查看到本地Git仓库与外界服务器版本库有哪些关联git remote showSEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile (master) $ git remote show origin这条命令就可以看到我本地版本库就只与Github上面的版本库做了相关联,如果我与Gitlab或者其他服务器做了关联,也会罗列出来git remote show + 版本库名字:了解详细信息SEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile (master) $ git remote show origin * remote origin Fetch URL: https://github.com/YQHP-YuKi/Gitleaning.git Push URL: https://github.com/YQHP-YuKi/Gitleaning.git HEAD branch: master Remote branch: master tracked Local branch configured for 'git pull': master merges with remote master Local ref configured for 'git push': master pushes to master (up to date)注:罗列出了我Fetch与Push拉取推送的网址,并且显示了与本地相关联的分支,且当前状态下相互合并的状态基于Git分支的开发模型develop分支(频繁变化の一个分支)test分支(供测试和产品等人员使用的一个分支,变化不是特别频繁)master分支(生产发布分支,变化非常不频繁の一个分支)bugfix(hotfix)分支(生产系统中出现了紧急的Bug,用于紧急修复的分支)使用SSH连接远程Github仓库使用HTTPS连接并不是我们连接Github仓库的主流方式,因为当使用HTTPS/HTTP协议建立本地仓库与远程厂库联系时,不需要进行任何配置,但是每次进行推送都需要输入账号密码,而使用SSH协议,只需要进行一次配置,就可以实现免密推送,我们主流连接主要是使用SSH进行连接,所以现在我重新连接Github仓库因为我是已经连接到了我的Github的仓库的,所以相当于我已经将远程仓库Github的IP地址添加到了本地信任地址中,如果每有关联,则执行此命令:git remote add origin +你的SSH链接接下来,使用以下命令生成本地计算机的公钥和私钥ssh-keygen进入sshcd ~/.ssh打印公钥cat id_rsa.pub注:在生成过程中,可以选择公钥和私钥的保存地址,默认是保存在.ssh文件夹下的,还可以设置密码,也可以不设置,直接回车即可生成公钥和私钥接下来我们要做的就是把生成的公钥部署到远程仓库Github上,如图所示:在该界面可以添加多个公钥,如果项目组有多个成员,或者一个人使用多台电脑可以设置多个公钥公钥与私钥的地址都在你ssh-keygen下面的文件路径里面,注意:一定要勾选Allow write access选项,否则无法将本地仓库代码推送到远程仓库,并且添加时要输入Github账号密码进行确认添加完成后,就可以在原来的界面看到新增的公钥了,这样使用该公钥的本地计算机就具有了读写这个远程仓库的权限了如果你原来也是用的HTTPS,这时候也配好了公钥,这时候只需要git clone +你原来的HTTPS让两个版本库一样,再去修改.git/config下的url即可:有3种方法可以查看到你是否已经将本地仓库关联到远程仓库:git remote //只显示远程仓库地址名 git remote -v //显示远程仓库地址名和对应URL git remote show origin//显示详细信息实际开发中,通常会使用SSH协议进行本地仓库与远程仓库的连接,因为只需要配置一次公钥,就可以免密推送,十分方便:添加账户SSH之前在Github上的Gitlearning仓库中添加了一把SSH公钥,但该SSH KEY仅限于本地与test仓库的通信,不能在其他仓库中使用如果我们想让Github上的所有仓库都使用同一把SSH KEY,就需要配置针对账号的SSH KEY了在Seeting中新建全局的SSH KEYGit协作SVN方式(典型模型)现有两位工作人员,分别为A与B,还有个就是远程仓库CA首先将本地仓库的代码推送push到远程仓库C中,此时A和C两个仓库的文件一致接下来B将C的代码拉取pull下来,此时A,B,C三者之间的仓库是一致的,然后A与B分别在各自的本地进行开发,并向各自的本地仓库进行了数次commit这时候A再向C推送修改过后的本地仓库文件,由于先前A,B,C三者一样,现在A做了修改,相当于C中文件A都有,所以不发生冲突,所以可以直接推送,不用先执行git pull这时候B也想向远程仓库C推送自己修改的文件,但却出现了失败,这是因为:此时的C中有A做出的修改,不能让B进行覆盖,此时B想要成功推送,只能先将C的文件拉取pull到本地,拉取pull时候有两种情况:成功(success):说明A与B修改的不是同一个文件,采用Fast-forward方式自动合并失败(fail):说明A与B修改了同一个文件,这时候就需要B手动解决冲突并合并B成功的将C中的文件pull到了本地并合并成功后,就能将B对本地仓库所做的修改推送push到远程仓库C了,此时C与B的版本库则也完全一样了,但与A不一样了注:在整个过程中,可以发现远程仓库C仅仅是起到了代码第三方托管的作用,不同于SVN的远程仓库C,SVN的仓库只有远程C一个,用户A与B都没有,假如C出问题了,会导致所有的提交信息都丢失,而git的分布式管理系统则不会出现这种情况本地远程分支当我在与Github仓库进行关联后,再执行git status时,我们会发现与以前没关联的时候有了一些细微的变化git中其实有三种分支:本地分支,本地远程分支,远程分支可以这样理解:本地远程分支是远程分支的一个镜像,并且在本地仓库与远程仓库之间起到一个桥梁的作用在没有办法直接查看远程仓库的时候,可以通过本地远程分支观察远程分支的变化情况,比如本地远程分支origin/main就对应着远程分支main正如图所示,origin/main为本地远程分支,代表的是远程仓库的main分支,而这个分支是在本地的,也就是说加上远程仓库的main分支,一共有三个master分支并且,当本地仓库中的每一个分支都有与之关联的远程分支之后,本地仓库都会创建对应的本地远程分支,他们所处的位置和关系如图所示可以这样理解:本地远程分支origin/master为远程分支master的本地化形式假设远程仓库和本地仓库文件内容是一样的,都只有两次提交,此时三个分支的状态如下图所示当我尝试从master切换到origin/master时,会出现这种:所以对于origin/master你是最好不要手动改变,因为这个分支是由git push和git pull来进行改变的模拟多人协作假如我是一名程序员B,我想把github上面的项目C给下载到本地,进行版本开发,我可以使用这条命令git clone +SSH 或者 +HTTPS我们可以发现名字自动就成了仓库C的名字我进去看看SEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile2 $ cd Gitlearning/ SEELE@DESKTOP-RHPQ0IE MINGW64 /F/Gitfile2/Gitlearning (main)可以发现自动切换到的master分支为什么会造成这种原因了,那是因为,我切回到程序员A提交的仓库看看我们程序员A最先前就是默认的master分支其实我们程序员B克隆仓库C不一定必须也叫Gitlearning,我们也可以自己设置,我现在就删除,重新创建一个,在SSH或者HTTPS后面跟你想要的仓库名字即可然后我们配置B程序员的仓库,使与程序员A保持不一致现在程序员A与程序员B的仓库还有远程C完全一样正式开始我们先在A这边更新一个文件,并提交到C这时候我们B查看一下版本:我们这时候想让B与AC都一样,则需要执行git pull命令可以看到我历史从A的047125d更新到了109b726仓库中多了一个ProgramAfile1.txt上图中有条横线表示,在pull操作的过程中B中的master分支与远程仓库C中的master分支采用了Fast-forward方式进行了合并,并达到了同步关于Fast-forward方式之前已经讲解过了,在上述合并过程中origin/master分支直接指向了最新提交,中间没有其他分支,也就不会出现合并冲突,这种合并方式称为快进,如图所示:这是一个理想的情况,很多情况下执行git pull操作时,都会出现合并冲突,需要手动解决冲突,再手动进行合并git pull同源合并冲突这时候我们ABC三者的仓库仍然是相同的,我开始分别对A与B进行修改这时候A与B修改的是同一个文件,但修改的东西是不一样的,且两个都分别提交到了本地的版本库这时候我们先让A进行git push,再让B进行git push试试这时候B出现了报错,显示你push失败是因为你的修改已经被其他仓库员所提前提交了,建议你使用git pull进行修改我们查看下C与B我们可以发现AC已经同步了,但是B是不一样的,我们就按照提示所做做git pull试试可以看到提示自动合并失败了,建议你手动修改那个文件并提交你的结果
标签与diffGit标签新建标签,标签有两种:轻量级标签(lightweight)与带有附注标签(annotated)创建一个轻量级标签git tag v1.0.0创建一个带有附注的标签git tag -a v1.0.1 -m 'release version'删除标签git tag -d tag_name我们先创建一个轻量级标签:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git tag v1.0.0查看下git reflog:a7ce3cd (HEAD -> test, tag: v1.0.0) HEAD@{0}: commit: finish the file a5300dd HEAD@{1}: commit: apply stash 3573a23 HEAD@{2}: reset: moving to HEAD 3573a23 HEAD@{3}: reset: moving to HEAD 3573a23 HEAD@{4}: reset: moving to HEAD发现没有任何多余的操作,只是增加了个指针,没有任何文件的移动我们再试试带注释的:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git tag -a v2.0.0 -m '2.0.0 released'如果想查看你有哪些标签,则直接使用命令:git tagA@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git tag v1.0.0 v2.0.0如果想在很多标签中查找某个标签,则可以加上这个标签的关键字并且在前面跟上-l参数,也可以跟上--list参数:$ git tag -l "v2.0.0" v2.0.0$ git tag --list "v2.0.0" v2.0.0删除标签:增加-d参数A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git tag -d v1.0.0 Deleted tag 'v1.0.0' (was a7ce3cd) A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git tag v2.0.0然后我们切换到master,再次查看git tag:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git checkout master Switched to branch 'master' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git tag v2.0.0可以发现在master中也能看到这个标签,可以说明标签不会随分支的改变而改变git blame这个命令在我们实际操作过程中,会经常用到,我们查看下它的文档:git blame --help git-blame - Show what revision and author last modified each line of a file可以查看一个文件最近的修改是哪个人所做的,例:$ git blame test1.txt ^61adf63 (YQHP-YuKi 2020-11-22 15:53:29 +0800 1) hello 9ed5c239 (YQHP-YuKi 2020-11-22 15:57:34 +0800 2) world b38e36d4 (YQHP-YuKi 2020-11-22 15:58:38 +0800 3) hello world 3573a232 (YQHP-YuKi 2020-11-22 16:02:40 +0800 4) hello hello hello 69d720db (YQHP-YuKi 2020-12-01 19:17:47 +0800 5) stash in master可以显示一个文件哪一行以及提交ID是由那一个人所做的diffgit diff这个命令是我们在项目开发时候会经常使用到的命令,主要是对比两个文件的差异性,在了解git diff之前,我们先了解一下普通的diff我们可以先查看一下自带的diff命令:$ which diff /usr/bin/diff然后创建两个txt文件,分别是a.txt与b.txt:a.txt:$ cat a.txt hello git hello a1 hello a2b.txt:$ cat b.txt hello git hello b1 hello b2我们使用diff查看一下:$ diff a.txt b.txt 2,3c2,3 < hello a1 < hello a2 --- > hello b1 > hello b2显示出这种,表示a.txt与b.txt的第二行与第三行不一样,a.txt的第二行与第三行是hello a1 hello a2,而b.txt的第二行与第三行是hello b1 hello b2,我们还可以在后面跟上参数-u:$ diff -u a.txt b.txt --- a.txt 2020-12-04 11:00:12.492672500 +0800 +++ b.txt 2020-12-04 11:00:36.444675600 +0800 @@ -1,3 +1,3 @@ hello git -hello a1 -hello a2 +hello b1 +hello b2注:以a.txt文件对比b.txt文件,两个文件的创建时间-1,-3第一个文件从第一行开始有3行+1,-3第二个文件从第一行开始有3行hello git这一行两个文件都是一样的,第一个文件删去-hello a1 -hello a2,加上+hello b1+ hello b2就成了第二个文件git diffgit diff对比的是你分支中工作区文件与暂存区文件的区别,例:我们先创建一个test.txt,在此之前记得git status查看状态,确保正常:$ cat test.txt hello world$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test.txt这时候我们先执行git diff试试:Administrator@bigdata037 MINGW64 /c/Gitfile (master) $ git diff因为我们此时的工作区与缓存区是没有任何差别的,所以diff检出不出任何差别,我们这时候再修改一下工作区的test.txt试试:$ cat test.txt hello BMC我们再执行git diff试试:Administrator@bigdata037 MINGW64 /c/Gitfile (master) $ git diff warning: LF will be replaced by CRLF in test.txt. The file will have its original line endings in your working directory diff --git a/test.txt b/test.txt index 3b18e51..000048a 100644 --- a/test.txt +++ b/test.txt @@ -1 +1 @@ -hello world +hello BMC注:因为两个文件都同名,所以git用了a/test.txt与b/test.txt做比较其中以暂存区的a/test.txt作为源文件,工作区的b/test.txt作为目标文件暂存区删除hello world增加hello BMC就成了工作区的test.txt我们对test.txt进行提交,查看一下状态:$ git status On branch master nothing to commit, working tree clean我们再修改test.txt:$ cat test.txt hello world hello Java如果我们想对比工作区与版本库中的文件,可以使用git diff,后面跟commit_id,如果想对比当前最新的一次版本库文件,则可以直接在后面跟HEAD例:$ git diff HEAD warning: LF will be replaced by CRLF in test.txt. The file will have its original line endings in your working directory diff --git a/test.txt b/test.txt index 000048a..5c2892a 100644 --- a/test.txt +++ b/test.txt @@ -1 +1,2 @@ -hello BMC +hello world +hello Javagit diff --cached比较的是版本库最新的提交与暂存区之间的差别例:最先的test1.txt:$ cat test1.txt hello world hello world hello hello hello stash in master现在修改的test1.txt:$ cat test1.txt hello world hello world对现在的test1.txt进行git add到缓存区:$ git add test1.txt执行git diff --cached:$ git diff --cached diff --git a/test1.txt b/test1.txt index 4783573..a08736b 100644 --- a/test1.txt +++ b/test1.txt @@ -1,5 +1,3 @@ hello world hello world -hello hello hello -stash in master跟原来一样的注释
checkout进阶与stashcheckout --讲解我们先查看下git status是否正常,然后再编辑test1.txt增加了no hallo:$ cat test1.txt hello world hello world hello hello hello no hello这时候我们再查看一下:$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt no changes added to commit (use "git add" and/or "git commit -a")发现是处于工作区了,我们使用git checkout --命令试试:$ git checkout -- test1.txt再查看一下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ cat test1.txt hello world hello world hello hello hello这时候就可以发现添加的no hallo已经不见了,并且git的状态也恢复正常了我们这时候还是修改test1.txt,对其加入no hallo:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ cat test1.txt hello world hello world hello hello hello no hello A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt no changes added to commit (use "git add" and/or "git commit -a")然后执行git add .,再查看一下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git add . A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test1.txt我们如果再次修改test1.txt会发生什么了?我们现在只是将工作区的第一次修改的test1.txt提交到了暂存区,试试吧:新的修改:must helloA@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ vim test1.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ cat test1.txt hello world hello world hello hello hello no hello must hellogit status查看:$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test1.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt我们这时候再试试git checkout --:$ git checkout -- test1.txt查看内容变化:$ cat test1.txt hello world hello world hello hello hello no hello发现第一次做的修改no hello保留下来了的,是保存在缓存区的,而第二次修改的must hello则没有了git status查看状态:$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test1.txt总结:git checkout -- test1.txt作用是:丢弃掉相对于暂存区中最后一次添加文件内容所做的修改验证:我们执行git reset HEAD命令将缓存区的no hallo放回到工作区:$ git reset HEAD test1.txt Unstaged changes after reset: M test1.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt no changes added to commit (use "git add" and/or "git commit -a")再执行git checkout --:$ git checkout -- test1.txt查看内容:$ cat test1.txt hello world hello world hello hello hello查看状态:$ git status On branch master nothing to commit, working tree cleancheckout回退版本我们原来学过git checkout切换分支,其实它也可以用来切换版本,但与我们上章所学的git reset --hard又有不同先git log查看一下:commit 3573a2322e2590fa8abcf6dca93b2ea6b01b9506 (HEAD -> master) Author: YQHP-YuKi <************@qq.com> Date: Sun Nov 22 16:02:40 2020 +0800 3hello in test1.txt commit b38e36d4fb88dcb629c855972eb86e5e9cbdf2b9 Author: YQHP-YuKi <***********@qq.com> Date: Sun Nov 22 15:58:38 2020 +0800 hello world in test1.txt commit 9ed5c2398694d005e7abf2468574d0fc91a42189 Author: YQHP-YuKi <***********@qq.com> Date: Sun Nov 22 15:57:34 2020 +0800 world in test1.txt commit 61adf63007461e6e5d79b19aa0ff09ff61033d76 Author: YQHP-YuKi <***********@qq.com@qq.com> Date: Sun Nov 22 15:53:29 2020 +0800 hello test1.txt假如这时候我们想回到9ed5c这个版本,我们可以这样做:git checkout+版本号:$ git checkout 9ed5c Note: switching to '9ed5c'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at 9ed5c23 world in test1.txt翻译:现在你已经进入到了一个游离的状态,你可以四周查看一下,做一些环境的改变,如果你想创建一个新的分支,你可以用git switch -c <new-branch-name>,现在你的HEAD不再是指向master,而是指向 9ed5c23 world in test1.txt我们查看一下test1.txt:$ cat test1.txt hello world查看历史:$ git log commit 9ed5c2398694d005e7abf2468574d0fc91a42189 (HEAD) Author: YQHP-YuKi <*************@qq.com> Date: Sun Nov 22 15:57:34 2020 +0800 world in test1.txt commit 61adf63007461e6e5d79b19aa0ff09ff61033d76 Author: YQHP-YuKi <************@qq.com@qq.com> Date: Sun Nov 22 15:53:29 2020 +0800 hello test1.txt我们对这个历史版本不做任何操作尝试回到master试试:$ git checkout master Previous HEAD position was 9ed5c23 world in test1.txt Switched to branch 'master'A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git branch * master发现又正常回到了master且没有任何多的分支增加,这几次操作的图片讲解:我们最先前是在master,执行git checkout 9ed5c后，HEAD不再指向master,而是指向9ed5c,所以只能看到先前的两次提交信息,看不到在此版本与master之间的任何提交信息那我们再回到9ed5c,并对其中的test1.txt进行改动试试:增加了checkout back$ cat test1.txt hello world checkout back再尝试返回到master:$ git checkout master error: Your local changes to the following files would be overwritten by checkout: test1.txt Please commit your changes or stash them before you switch branches. Aborting但是出现了报错:错误,你当前的改变文件将会重写test1.txt,请提交你的改变或者stash他们在你改变分支前那我们commit一下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile ((9ed5c23...)) $ git add .A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile ((9ed5c23...)) $ git commit -m "commit on 9ed5c again" [detached HEAD 00fd224] commit on 9ed5c again 1 file changed, 1 insertion(+) A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile ((00fd224...))这时候就发生了变化,我们从9ed5c23变为了00fd224,查看历史看看:$ git log commit 00fd224b50c9ed5390257617220ad0e35064571b (HEAD) Author: YQHP-YuKi <**************@qq.com> Date: Wed Nov 25 09:31:10 2020 +0800 commit on 9ed5c again commit 9ed5c2398694d005e7abf2468574d0fc91a42189 Author: YQHP-YuKi <**************@qq.com> Date: Sun Nov 22 15:57:34 2020 +0800 world in test1.txt commit 61adf63007461e6e5d79b19aa0ff09ff61033d76 Author: YQHP-YuKi <**************@qq.com@qq.com> Date: Sun Nov 22 15:53:29 2020 +0800 hello test1.txt这时候的状态图:我们再尝试去切换回到master:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile ((00fd224...)) $ git checkout master Warning: you are leaving 1 commit behind, not connected to any of your branches: 00fd224 commit on 9ed5c again If you want to keep it by creating a new branch, this may be a good time to do so with: git branch <new-branch-name> 00fd224 Switched to branch 'master' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master)这时候就只是警告了:警告你正在离开一个落后的commit,没有与你的分支有任何联系,提交信息为: 00fd224 commit on 9ed5c again,如果你想保存就创造一个新的branch,这时候也许是个好时间去创造,命令为: git branch 00fd224这时候的状态图:创建一个新的分支:$ git branch newcommot 00fd224查看下:$ git branch * master newcommot我们切换到newcommit看看:$ git log --graph * commit 00fd224b50c9ed5390257617220ad0e35064571b (HEAD -> newcommot) | Author: YQHP-YuKi <1465722762@qq.com> | Date: Wed Nov 25 09:31:10 2020 +0800 | | commit on 9ed5c again | * commit 9ed5c2398694d005e7abf2468574d0fc91a42189 | Author: YQHP-YuKi <1465722762@qq.com> | Date: Sun Nov 22 15:57:34 2020 +0800 | | world in test1.txt | * commit 61adf63007461e6e5d79b19aa0ff09ff61033d76 Author: YQHP-YuKi <1465722762@qq.com@qq.com> Date: Sun Nov 22 15:53:29 2020 +0800 hello test1.txt可以看到我们在9ed5c上面的新提交00fd2这个已经成为了一个新的分支此时的状态图:总结:通过checkout进行版本回退会造成游离的提交对象链,需要额外创建一个分支进行保存因此,使用checkout进行版本回退的思路为,先切换到想要回退的提交版本,再删除进行版本回退的分支dev,最后,创建一个新的dev分支指向游离的提交对象链,完成分支dev的版本回退只要有分支指向,提交就不会被丢弃stash我们在msater执行git status检查一下:master:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean然后创建一个新的分区test:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git checkout -b test Switched to a new branch 'test'然后回到master上修改test1.txt,并将其提交:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ vim test1.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git commit -am "stash in master" [master 69d720d] stash in master 1 file changed, 1 insertion(+) A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean查看下修改的test1.txt:$ cat test1.txt hello world hello world hello hello hello stash in master这时候我们回到test分支,也对test1.txt进行修改,并进行查看一下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello status in test假如这时候你公司叫你回到master进行一个另一个文件的修改或者版本控制,这时候你想回到master分支:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git checkout master error: Your local changes to the following files would be overwritten by checkout: test1.txt Please commit your changes or stash them before you switch branches. Aborting翻译:你本地的改变的test1.txt文件会被checkout所重写覆盖,请将文件进行提交或者stash在你改变分支之前我们尝试将文件从工作区放进缓存区试试:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git add . A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git status On branch test Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test1.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git checkout master error: Your local changes to the following files would be overwritten by checkout: test1.txt Please commit your changes or stash them before you switch branches. Aborting但是还是出现这个报错,说明无论是工作区还是缓存区的修改都会被checkout所覆盖,原因如图:我们最先前的msater已经做出了改变,但这个test分支还是在第一次的master的分支上分离出来的,是处于一个游离的状态,所以现在要切换到现在的msater,就会被现在的master所覆盖这种情况在工作日常开发中很常见,但在develop分支上开发新功能的时候,master分支出现紧急情况需要切换回去进行修复,但是当前分支的新功能还没完全开发完全,贸然切换分支,会导致所做的修改而被覆盖,而且也不可以随意的commit,因为你这分支版本还是处于测试版本,不能随意提交到版本库中,这时候你就需要用到stash我们将缓存区的test1.txt文件放回到工作区:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git reset HEAD test1.txt Unstaged changes after reset: M test1.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git status On branch test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt no changes added to commit (use "git add" and/or "git commit -a")然后执行git stash:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash Saved working directory and index state WIP on test: 3573a23 3hello in test1.txt查看下test1.txt:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello发现所做的修改stash in test没有了,这时候我们再切换到master:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git checkout master Switched to branch 'master'发现没问题了,再切换到test分支并且查看test1.txt:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git checkout - Switched to branch 'test' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello发现我们所做的修改还是没有,那stash in test到底在哪了?其实通过了git stash将test分支上工作区或暂存区中的修改,提交到了stash区域进行保存,并将test分支退回到修改前的状态,如下图所示:切换到master分支时test分支上的修改依旧会被覆盖,所以,再次回到test分支时需要从stash区域中恢复切换分支前所保存的修改查看stash日志我们可以通过git stash list查看stash的版本日志:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash list stash@{0}: WIP on test: 3573a23 3hello in test1.txt注:后面的WIP是working in process的意思,表示的是正在进行的工作这样就看到我们先前stash in test的日志了,编号为stash@{0},我们也可以对stash日志进行每个日志命名,例如我们再次修改test1.txt:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ vim test1.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello stash try again通过参数save可以命名,例如:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash save 'stash try again' Saved working directory and index state On test: stash try again再git stash list查看一下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash list stash@{0}: On test: stash try again stash@{1}: WIP on test: 3573a23 3hello in test1.txt这样我们就看到1的第一提交,0第二次提交的try again想要恢复stash所做的修改前模样,主要有三种方法:git stash popgit stash applygit stash apply stash@{number}git stash pop我们使用git stash pop看看:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash pop On branch test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (6e4d554894d1db504cf525db30b3f7196ce1478f) A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello stash try again A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash list stash@{0}: WIP on test: 3573a23 3hello in test1.txt发现第二次修改的try again stash恢复回来了,git stash list中的第二次历史信息没了,而且状态也变为工作区了git stash pop作用:恢复并删除stash中存储的最新修改git stash apply我们再使用git stash apply试试:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash apply On branch test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test1.txt no changes added to commit (use "git add" and/or "git commit -a") A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello stash try again A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash list stash@{0}: On test: try again stash stash@{1}: WIP on test: 3573a23 3hello in test1.txt可以发现跟pop相比,也是恢复到了工作区,但是git stash list中的历史记录还是存在git stash apply:恢复但不删除stash中存储的最新修改如果我们想删除git stash list中的记录,我们需要手动删除,命令是:git stash drop stash@{number},例:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash drop stash@{0} Dropped stash@{0} (8307e8403059797eed5d2c4f1356649146e167d1)再查看一下list:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash list stash@{0}: WIP on test: 3573a23 3hello in test1.txtA@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello stash try again就发现没了,而且文件也改回来了,如果这时候我们使用git stash pop,会发生什么了?$ git stash pop error: Your local changes to the following files would be overwritten by merge: test1.txt Please commit your changes or stash them before you merge. Aborting The stash entry is kept in case you need it again.这时候又出现要求你提交要不就stash的报错,那我们进行提交:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git commit -am 'apply stash' [test a5300dd] apply stash 1 file changed, 1 insertion(+) A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git status On branch test nothing to commit, working tree clean我们再执行git stash pop:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ git stash pop Auto-merging test1.txt CONFLICT (content): Merge conflict in test1.txt The stash entry is kept in case you need it again. A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello <<<<<<< Updated upstream stash try again ======= status in test >>>>>>> Stashed changes这时候发生了合并冲突,这是因为,stash中保存的每一次修改代表的都是一个版本:如上图所示,在test分支上,进行第一次修改后,通过git stash将该修改作为修改0保存到stash中,此时分支中的文件并没有发生改变进行第二次修改后,通过git stash将修改作为修改1保存到stash中,分支中的文件依旧没有发生改变,此时的stash中相当于保存着同一分支上两个修改后的版本此时通过git stash apply取出0,与test分支进行合并,再通过git stash pop取出1,再次与test分支进行合并,两个版本合并自然会发生冲突如果想解决冲突,则vim修改文件即刻:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (test) $ cat test1.txt hello world hello world hello hello hello status in testgit stash apply stash@{0}指定恢复的版本,就跟git reset指定log一样总结:git stash pop：恢复并删除stash中存储的最新修改git stash apply：恢复但不删除stash中存储的最新修改git stash apply stash@{0}：恢复但不删除stash中存储的特定提交画图图片转载:AhuntSun
Git訓練場-同是天涯淪落人 相逢何必曾相識.assets
分支进阶与版本回退fast-forward如果可能,合并分支时Git会使用fast-forward模式在这种模式下,删除分支时会丢掉分支信息合并时加上--no-ff参数会禁用fast-forward,这样会多出一个commit idgit merge --no-ff查看log,以图形化的方式git log --graph这样dev虽然在合并后也是在分支上的,而且master并不会往前前进一个位子,而是直接commit一次提交记录,再与dev进行合并尝试--no-ff参数首先我们查看一下当前master与dev的git log,对比一下,会发现两个的git log因为上一章的合并导致完全一样,然后我们切换到dev修改一下文件,并且提交:$ git status On branch dev nothing to commit, working tree clean A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ cat test.txt I am YQHP-YuKi hello everyone this is master this is dev again这时候我们再切回到master,使用git merge --no-ff dev试试:出现了这个vim界面,显示出一条提交信息Merge branch 'dev' into master # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.$ git merge --no-ff dev Merge made by the 'recursive' strategy. test.txt | 2 ++ 1 file changed, 2 insertions(+)这时候我们再查看一下master的git log,与之前dev的git log比较一下:经过git merge --no-ff的master:commit 534d7bb70f5e95ba74af17c252e8c14d27ce16d1 (HEAD -> master) Merge: a41fd9e 74bee32 Author: YQHP-YuKi <**********@qq.com> Date: Fri Nov 20 17:37:35 2020 +0800 Merge branch 'dev' into master commit 74bee3236352ae346395dca7f3de1675df548a0c (dev) Author: YQHP-YuKi <**********@qq.com> Date: Fri Nov 20 17:22:23 2020 +0800 this is dev again commit a41fd9e529c9a9e0b746745beae653b6736dac46 Merge: 6162e11 0a3a478 Author: YQHP-YuKi <**********@qq.com> Date: Thu Nov 19 15:42:10 2020 +0800 Merge branch 'dev' into mastercommit 74bee3236352ae346395dca7f3de1675df548a0c (HEAD -> dev) Author: YQHP-YuKi <1465722762@qq.com> Date: Fri Nov 20 17:22:23 2020 +0800 this is dev again commit a41fd9e529c9a9e0b746745beae653b6736dac46 (HEAD -> dev, master) Merge: 6162e11 0a3a478 Author: YQHP-YuKi <**********@qq.com> Date: Thu Nov 19 15:42:10 2020 +0800 Merge branch 'dev' into master commit 0a3a478dc18d6b39a53e7ad3cbbecdda0531071a Author: YQHP-YuKi <***********@qq.com> Date: Thu Nov 19 15:25:09 2020 +0800 this is dev in test.txt commit 6162e11b99c56f3e2e0f8c8bce933bbaa7081f26 Author: YQHP-YuKi <***********@qq.com> Date: Thu Nov 19 15:22:15 2020 +0800 this is master in test.txt可以发现master的第一条是一条单独多出来的commit历史记录,如果使用fast-forward的话,master的log一个会与dev的log一样,我们还可以使用git log --graph查看:* commit 534d7bb70f5e95ba74af17c252e8c14d27ce16d1 (HEAD -> master) |\ Merge: a41fd9e 74bee32 | | Author: YQHP-YuKi <***********@qq.com> | | Date: Fri Nov 20 17:37:35 2020 +0800 | | | | Merge branch 'dev' into master | | | * commit 74bee3236352ae346395dca7f3de1675df548a0c (dev) |/ Author: YQHP-YuKi <***********@qq.com> | Date: Fri Nov 20 17:22:23 2020 +0800 | | this is dev again | * commit a41fd9e529c9a9e0b746745beae653b6736dac46 |\ Merge: 6162e11 0a3a478 | | Author: YQHP-YuKi <*********@qq.com> | | Date: Thu Nov 19 15:42:10 2020 +0800 | | | | Merge branch 'dev' into master | | | * commit 0a3a478dc18d6b39a53e7ad3cbbecdda0531071a | | Author: YQHP-YuKi <**********@qq.com> | | Date: Thu Nov 19 15:25:09 2020 +0800 可以看到原本使用fast-forward就应该在dev那就停住了,使用--no-ff就多了第一条commit信息版本回退我们删除先前的Gitfile,重新创建一个git厂库:$ rm -rf *$ cd ..$ rm -rf Gitfile$ git init Initialized empty Git repository in E:/Gitfile/.git/这时候创建一个test1.txt,向里面分4次添加4条信息,分4次提交：$ cat test1.txt hello world hello world hello hello hello$ git log --pretty=oneline --abbrev-commit 3573a23 (HEAD -> master) 3hello in test1.txt b38e36d hello world in test1.txt 9ed5c23 world in test1.txt 61adf63 hello test1.txt这时候我们想回退到第3次提交,也就是hello world那次:Git回退版本回退到上一版本git reset --hard HEAD^git reset --hard HEAD~1返回到某一版本hard HEAD^我们想回退到上一版本,使用这条命令：git reset --hard HEAD^$ git reset --hard HEAD^ HEAD is now at b38e36d hello world in test1.txt想再回退2个版本:$ git reset --hard HEAD^^ HEAD is now at 61adf63 hello test1.txt这时候用git log查看一下:$ git log commit 61adf63007461e6e5d79b19aa0ff09ff61033d76 (HEAD -> master) Author: YQHP-YuKi <************@qq.com> Date: Sun Nov 22 15:53:29 2020 +0800 hello test1.txt如果我们这时候还是想回到第4次提交那,可以直接后面跟版本号:$ git reset --hard 3573a HEAD is now at 3573a23 3hello in test1.txt$ cat test1.txt hello world hello world hello hello hellohard HEAD~1如果我们想回退到前3 5次这种很前的提交,则后面可以直接跟数字:$ git reset --hard HEAD~3 HEAD is now at 61adf63 hello test1.txt注释:3是从你当前记录开始的前3次提交,相当于是4-3=1,是版本1,如果是~1,则是版本3hard commit_id我们如果想直接回到某次提交,则可以直接跟那次的commit_id:第一次:$ git reset --hard 61adf HEAD is now at 61adf63 hello test1.txt第四次:$ git reset --hard 3573a HEAD is now at 3573a23 3hello in test1.txtgit reflog如果我们在版本1,想回到版本4,但又不记得版本4的commit_id了,我们可以用使用这个命令查看:$ git reflog 3573a23 (HEAD -> master) HEAD@{0}: reset: moving to 3573a23 61adf63 HEAD@{1}: reset: moving to HEAD 61adf63 HEAD@{2}: reset: moving to HEAD 61adf63 HEAD@{3}: reset: moving to HEAD 61adf63 HEAD@{4}: reset: moving to 61adf 3573a23 (HEAD -> master) HEAD@{5}: reset: moving to 3573a 61adf63 HEAD@{6}: reset: moving to 61adf 3573a23 (HEAD -> master) HEAD@{7}: reset: moving to 3573a 61adf63 HEAD@{8}: reset: moving to HEAD~3 3573a23 (HEAD -> master) HEAD@{9}: reset: moving to 3573a b38e36d HEAD@{10}: reset: moving to HEAD~1 3573a23 (HEAD -> master) HEAD@{11}: reset: moving to 3573a 61adf63 HEAD@{12}: reset: moving to HEAD 61adf63 HEAD@{13}: reset: moving to HEAD^^ b38e36d HEAD@{14}: reset: moving to HEAD^ 3573a23 (HEAD -> master) HEAD@{15}: commit: 3hello in test1.txt b38e36d HEAD@{16}: commit: hello world in test1.txt 9ed5c23 HEAD@{17}: commit: world in test1.txt 61adf63 HEAD@{18}: commit (initial): hello test1.txtgit reflog是操作日志,这样我们就可以看到我们操作的任何版本日志的id了
Git訓練場-人生代代無窮已 江月年年望相似
.gitignore与分支.gitignore一般来说每个Git项目中都需要一个.gitignore文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中,比如Android项目中的iml文件及build目录下编译生成的文件,项目中经常会有很多临时文件, 如临时的编译中间文件, 通常这些文件不需要加入到版本控制中. 如何在提交的时候跳过这些文件? 一种办法是很繁琐的在 git add 的时候手动添加需要加入版本控制的文件, 这种方法不仅繁琐也很容易犯错.还有一个办法就是使用 gitignore 文件哪些文件需要放入到.gitignore里通常, 能够通过其他文件自动生成的都不需要放入版本控制, 如编译产生的临时文件. 还有, 操作系统会创建自动创建一些文件, 如缩略图, 这些也不需要放入版本控制 最后, 某些比较敏感的文件, 比如包含数据库连接密码的配置文件也不要放到公共 git 仓库里 不过, 并不是一定如此, 还是得具体问题具体分析总结gitignore 是用来过滤不想加入版本控制的文件用的可以找到很多现成的 gitignore 文件你应该尽早编写gitignore并及时提交具体操作讲解创建一个properties文件$ echo "my project configuration" > settings.properties查看状态$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) settings.properties nothing added to commit but untracked files present (use "git add" to track)会显示这个properties文件一直处于是未追踪的状态,不管你以后是否提交了txt文件到版本库中,都会一直显示未追踪,但按理来说,我们不能将项目有关的配置文件提交到Git的版本库中,这时候就需要properties放进版本库创建.gitignore$ vim .gitignore查看文件以及git status$ ls -al total 59 drwxr-xr-x 1 A 197609 0 11月 15 20:34 ./ drwxr-xr-x 1 A 197609 0 11月 15 10:20 ../ drwxr-xr-x 1 A 197609 0 11月 15 20:29 .git/ -rw-r--r-- 1 A 197609 0 11月 15 20:34 .gitignore -rw-r--r-- 1 A 197609 25 11月 15 20:29 settings.properties -rw-r--r-- 1 A 197609 16 11月 14 17:17 test.txt -rw-r--r-- 1 A 197609 13 11月 14 11:56 test2.txt$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore settings.properties nothing added to commit but untracked files present (use "git add" to track)这时候我们再vim .gitignore$ vim .gitignore在.gitignore里面加入文件名 settings.properties$ cat .gitignore settings.properties我们这时候再git status一下,就可以发现 settings.properties不见了$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore nothing added to commit but untracked files present (use "git add" to track)我们提交.gitignore到暂存区和版本库中$ git add .gitignore warning: LF will be replaced by CRLF in .gitignore. The file will have its original line endings in your working directory$ git commit -m 'add .gitignore' [master 095b97f] add .gitignore 1 file changed, 2 insertions(+) create mode 100644 .gitignore查看一下$ git status On branch master nothing to commit, working tree clean$ ls -al total 60 drwxr-xr-x 1 A 197609 0 11月 15 20:37 ./ drwxr-xr-x 1 A 197609 0 11月 15 10:20 ../ drwxr-xr-x 1 A 197609 0 11月 15 20:42 .git/ -rw-r--r-- 1 A 197609 21 11月 15 20:37 .gitignore -rw-r--r-- 1 A 197609 25 11月 15 20:29 settings.properties -rw-r--r-- 1 A 197609 16 11月 14 17:17 test.txt -rw-r--r-- 1 A 197609 13 11月 14 11:56 test2.txt可以发现,setting.properties文件还是在的,但是被Git给忽略掉了,说明我们的项目的配置文件,无论你做任何修改,Git都会忽略掉再试一次创建一个a.b文件$ echo 'another file' > a.b$ cat .gitignore settings.properties a.b$ git add . warning: LF will be replaced by CRLF in .gitignore. The file will have its original line endings in your working directory$ git commit -m 'update .gitignore' [master df216c5] update .gitignore 1 file changed, 1 insertion(+), 1 deletion(-)$ git status On branch master nothing to commit, working tree clean忽略文件.gitignore文件*.a忽略所有.a结尾的文件!lib.a但lib.a除外/TODO仅仅忽略项目根目录下的TODO文件,不包括subdir/TODObuild/忽略build/目录下的所有文件doc/*.txt会忽略doc/notes.txt但不包括doc/server/arch.txt例:创建一个test3.txt,并且查看git status$ echo 'test3' >test3.txt$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore test3.txt nothing added to commit but untracked files present (use "git add" to track)修改一下.gitignore,再查看下git status/test3.txt$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore发现test3.txt没了,但是这时候我们再创建一个mydir目录,在mydir里面创建一个mydirtest3.txt, 再查看git status$ cat mydirtest3.txt test3$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore mydir/注意:这时候我们在Gitfile根目录下进行git status与在mydir目录下进行git status是不一样的,对比效果如下:Gitfile .gitignore mydir/mydir ../.gitignore ./如果想把mydirtest3.txt也忽略掉,可以在.gitignore里面添加:/*/mydirtest3.txt这样mydirtest3.txt就忽略掉了,但如果我们每层目录下都要这样写,那样就很麻烦,例如:我们在mydirtest下面创建一个目录yourdir,然后在里面也创建一个test3.txt,查看一下:No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore mydir/我们想把所有目录下的test3.txt都忽略掉,可以加上两个**/**/test3.txt这样就都忽略掉了build如果我们在.gitignore忽略文件前面加上#注释掉,则该忽略失效,我们想使一个目录下的所有文件都失效,可以这样:mydir/这样mydir下面的所有文件就都忽略掉了重要的分支当我使用命令git init初始化一个Git厂库的时候,Git给我们初始化了一个master主分支,这时候我们如果想查看我们是在哪个分支,可以使用一个命令查看:$ git branch如果想创建一个新的分支,则可以在命令后面加入参数,参数就是新的分支名字,列如：$ git branch new_branch再使用git branch查看,就会发现多了一个分支了:$ git branch * master new_branch注:如果我们最开始就git init一个Git厂库,啥都没有,然后就git branch是会报错的,那是因为你暂存区与版本库没有任何东西,所以想要创建新的分支,必须是要工作区的在不同分支之间来回穿梭,与创建后立即进入如果想在分支之间切换,则可以使用命令git checkout + 分支名,例:$ git checkout new_branch Switched to branch 'new_branch'checkout后面可以跟一个参数,就可以在创建一个新的分支后立即进入,这个参数就是-b,例:$ git checkout -b new_branch Switched to a new branch 'new_branch'如果也在此分支立刻返回到先前所在的分支,也如同切换文件一样,可以跟上-,例:当前我是在new_branch,想回到master$ git checkout - Switched to branch 'master'我们在不同的分支切换,其实就是在master与分支之间切换,在windows Mac或虚拟机的图形化界面下,查看Gitfile会发现在切换分支时,文件是都在Gitfile master那个页面中变幻,而不会是创建了新的文件夹，我们在另外的分支中创建文件,如果没有合并分支,在master中都是看不到的删除分支想要删除分支,要分为两种情况:无任何修改与已有修改无任何修改的分支删除如果我们创建一个分支,没有任何的修改,意思是跟master一样,想要删除这个分支,则直接在git branch后面加参数-d,例如下:$ git branch -d new_branch Deleted branch new_branch (was df216c5).这样new_branch就删除掉了已有修改操作的分支删除我们重新创建一个new_branch并且向里面添加一个test1.txt,让这个文件提交到版本库中,再使用-d参数试试：已提交test1.txt到new_branch的版本库：A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (new_branch) $ git commit -m 'new_branch test1.txt first' [new_branch 5e0c211] new_branch test1.txt first 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test1.txt使用git log查看,可以很清楚的看到test1.txt是在new_branch提交的记录:commit 5e0c211f1c85a429cf8458eeb91a40043aaca6be (HEAD -> new_branch) new_branch test1.txt first我们回到master,试图用-d参数删除new_branch:$ git branch -d new_branch error: The branch 'new_branch' is not fully merged. If you are sure you want to delete it, run 'git branch -D new_branch'.出现提示,提示你new_branch跟master是没有合并的两个分区,如果想在没合并的前提下删除new_branch,可以使用参数-D进行强制删除,那我们使用-D强制删除试试:$ git branch -D new_branch Deleted branch new_branch (was 5e0c211).$ git branch * master发现new_branch已经删除了，并且先前在new_branch中提交test1.txt的git log也已经删除了,我们再创建new_branch与test1.txt这时候来合并试试,合并两个版本需要使用使用git merge这个命令,我们回到master使用$ git merge new_branch Merge made by the 'recursive' strategy. test1.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test1.txt这时候发现我们的master中的test1.txt已经变为了new_branch中的test1.txt这时候我们再调用-d参数,看是否能删除new_branch:$ git branch -d new_branch Deleted branch new_branch (was afa98a1). A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git branch * master我们可以使用-v参数查看当前分支最新的一条提交信息,例如:$ git branch -v * master f25e8c3 Merge branch 'new_branch' into master分支的本质一个commit对象链:一条工作记路线Git每次提交都记录着上一次的提交ID,这样就形成了一条完整的时间线,每一次的Parent都指向上一次的提交IDHEAD指向的是当前分支master指向提交HEAD并不指向当前提交,而是指向当前分支,而master才是指向当前提交,所以HEAD指向masterdev的意思是指我使用git branch dev,是在这时候创建了一个dev分支,相当于你执行了git checkout -b dev这条命令,创建了dev分支并且进入了此分支,所以HEAD是指向dev的而HEAD是在哪了?HEAD是在.git目录下,我们现在查看一下:$ cd .git A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile/.git (GIT_DIR!) $ cat HEAD ref: refs/heads/master可以显示当前HEAD是指向的master我们创建一个dev分支,再查看一下HEAD:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git checkout -b dev Switched to a new branch 'dev' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ cd .git A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile/.git (GIT_DIR!) $ cat HEAD ref: refs/heads/dev可以看到当前HEAD就是在dev了,就如图所示的样子了此图显示的状态是,我们在dev分支上,又做了一次提交,就像我们在dev上面修改创建了一个文件,做了一次提交,所以我们如果在master上面使用git branch -d命令,会显示两个分支没有合并,只能使用git branch -D强制删除我们可以使用git log对比一下master与dev的log:dev:commit 4ca3bca9404b69f665cb950903c332821987c58d (HEAD -> dev) Author: YQHP-YuKi <************@qq.com> Date: Thu Nov 19 15:05:19 2020 +0800 add new line on dev commit f25e8c3063b088c3aa1f1239891538780c167cd2 (master) Merge: 7d9a3e0 afa98a1 Author: YQHP-YuKi <************@qq.com> Date: Tue Nov 17 23:18:47 2020 +0800 Merge branch 'new_branch' into master commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0 Author: YQHP-YuKi <************@qq.com> Date: Tue Nov 17 23:17:49 2020 +0800master:commit f25e8c3063b088c3aa1f1239891538780c167cd2 (HEAD -> master) Merge: 7d9a3e0 afa98a1 Author: YQHP-YuKi <************@qq.com> Date: Tue Nov 17 23:18:47 2020 +0800 Merge branch 'new_branch' into master commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0 Author: YQHP-YuKi <***********@qq.com> Date: Tue Nov 17 23:17:49 2020 +0800 deledt .gitignore commit afa98a1419abcd04ffdbd95d2398035e40f3b540 Author: YQHP-YuKi <************@qq.com> Date: Tue Nov 17 23:11:40 2020 +0800 new_branch test1.txt second我们可以发现dev的第二条提交信息是master的第一条提交信息,dev第3条提交信息是master第2条提交信息然后我们在master上面执行git merge$ git merge dev Updating f25e8c3..4ca3bca Fast-forward test.txt | 1 + 1 file changed, 1 insertion(+)显示更新了f25e8c3,我们再在master上面git log一下:commit 4ca3bca9404b69f665cb950903c332821987c58d (HEAD -> master, dev) Author: YQHP-YuKi <***********@qq.com> Date: Thu Nov 19 15:05:19 2020 +0800 add new line on dev commit f25e8c3063b088c3aa1f1239891538780c167cd2 Merge: 7d9a3e0 afa98a1 Author: YQHP-YuKi <***********@qq.com> Date: Tue Nov 17 23:18:47 2020 +0800 Merge branch 'new_branch' into master commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0 Author: YQHP-YuKi <***********@qq.com> Date: Tue Nov 17 23:17:49 2020 +0800 deledt .gitignore可以发现master的log与dev的log已经相同了两个分支不互通的情况假如我们在master上面做了修改,也在dev上面做了修改,会发生什么了?我们先修改master:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ vim test.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git add . A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git commit -m "this is master in test.txt" [master 6162e11] this is master in test.txt 1 file changed, 1 insertion(+) A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean再在dev上面修改:$ git checkout dev Switched to branch 'dev' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ vim test.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ git add . A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ git commit -m 'this is dev in test.txt' [dev 0a3a478] this is dev in test.txt 1 file changed, 1 insertion(+)我们回到master,尝试使用git merge试试:$ git checkout master Switched to branch 'master' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git merge dev Auto-merging test.txt CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.报错了,显示了在合并test.txt时,因为两个文件不符合,出现了报错我们查看一下test.txt$ cat test.txt I am YQHP-YuKi hello everyone <<<<<<< HEAD this is master ======= this is dev >>>>>>> dev因为HEAD代表的是当前分支,我们当前是在master,所以master的是this is master,dev的是this is dev,我们删除dev中的this is dev试试:可以直接在master中vim test.txt,然后按dd删除:$ cat test.txt I am YQHP-YuKi hello everyone this is master查看一下状态:$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: test.txt no changes added to commit (use "git add" and/or "git commit -a")这时候我们使用git add这条命令,但这时的git add并非以前的git add意思,这时候的意思是告诉git我已经解决了这个冲突$ git add test.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master|MERGING) $ git status On branch master All conflicts fixed but you are still merging. (use "git commit" to conclude merge)我们使用git commit可以完成mearing:$ git commit [master a41fd9e] Merge branch 'dev' into master A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean保存退出文档即可查看一下test.txt:$ cat test.txt I am YQHP-YuKi hello everyone this is master已经变为了master的了,我们git log一下:master:commit a41fd9e529c9a9e0b746745beae653b6736dac46 (HEAD -> master) Merge: 6162e11 0a3a478 Author: YQHP-YuKi <***********@qq.com> Date: Thu Nov 19 15:42:10 2020 +0800 Merge branch 'dev' into master commit 0a3a478dc18d6b39a53e7ad3cbbecdda0531071a (dev) Author: YQHP-YuKi <***********@qq.com> Date: Thu Nov 19 15:25:09 2020 +0800 this is dev in test.txt commit 6162e11b99c56f3e2e0f8c8bce933bbaa7081f26 Author: YQHP-YuKi <***********@qq.com> Date: Thu Nov 19 15:22:15 2020 +0800 this is master in test.txt commit 4ca3bca9404b69f665cb950903c332821987c58d Author: YQHP-YuKi <************@qq.com> Date: Thu Nov 19 15:05:19 2020 +0800dev:commit 0a3a478dc18d6b39a53e7ad3cbbecdda0531071a (HEAD -> dev) Author: YQHP-YuKi <**************@qq.com> Date: Thu Nov 19 15:25:09 2020 +0800 this is dev in test.txt commit 4ca3bca9404b69f665cb950903c332821987c58d Author: YQHP-YuKi <**************@qq.com> Date: Thu Nov 19 15:05:19 2020 +0800 add new line on dev commit f25e8c3063b088c3aa1f1239891538780c167cd2 Merge: 7d9a3e0 afa98a1 Author: YQHP-YuKi <**************@qq.com> Date: Tue Nov 17 23:18:47 2020 +0800 Merge branch 'new_branch' into master commit 7d9a3e074e8c3265e416a738543d7c5cd820c9e0 Author: YQHP-YuKi <***************@qq.com> Date: Tue Nov 17 23:17:49 2020 +0800会发现master比dev的更新记录更快一步,这一步是:Merge branch 'dev' into master,但现在两边的test.txt一样吗?查看下:master:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ cat test.txt I am YQHP-YuKi hello everyone this is masterdev:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ cat test.txt I am YQHP-YuKi hello everyone this is dev发现两边仍然不一样,那我们切换到dev试试在dev中git merge一下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (dev) $ git merge master Updating 0a3a478..a41fd9e Fast-forward test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)居然没有报错,并且成功的将master给合并过来了,这是为什么了?合并讲解这是最先我们dev与master都不一样的时候的样子,两个分支都有修改这是我们在master进行了git add test.txt后的样子,相当于master向前跳了一个版本,但这个版本是跟一起那个master一样的,所以有这样的显示:Merge branch 'dev' into master,这样master就比dev更快一步了,并且两个分支建立了联系我们再在dev中将master合并过来,这样使用git merge master或者在master中使用git merage dev就不会出现报错了,这样两个分支就完成合并了参考资料B站评论区大佬博客:https://www.cnblogs.com/AhuntSun-blog/p/12745183.htmlgit 官方文档: https://git-scm.com/docs/gitignore segmentfault https://segmentfault.com/a/1190000000522997 廖雪峰的博客 : [http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013758404317281e54b6f5375640abbb11e67be4cd49e0000]
Git訓練場-雲想衣裳花想容 春風弗蘭露華容
简单介绍Git官网:https://git-scm.com/想学习Git，个人建议有Linux的基础，因为Git本来就是Linux大牛所创造的,所以大部分命令都与Linux有关，它是一个分布式版本控制系统(DVCS)。Git GitHub GitLab介绍Git是一个版本控制软件GitHub与GitLab都是用于管理版本的服务端软件GitH提供免费服务(代码需要公开)及付费服务(代码私有化)GitLab用于在企业内部管理Git版本库,功能上类似于GitHub文件的三种状态已修改(modified)已缓存(staged)已提交(committed)Git安装Linux(Ubantu)$ sudo apt install git-allCentos或RHEL$ sudo dnf install git-allMac安装命令行工具(如已安装Xcode,命令行工具会在首次启动Xcode时提示安装)在 Mac 上安装 Git 有多种方式。 最简单的方法是安装 Xcode Command Line Tools。 Mavericks （10.9） 或更高版本的系统中，在 Terminal 里尝试首次运行 git 命令即可。$ git --versionhomebrewmacportsWindows通过msysGit:https://git-scm.com/建议使用Git命令行，方便快捷简单,GUI繁琐个人感觉花里胡哨,本人是在Windows10下进行的Git，安装完Git后，直接右键就可以看到一个Git Bash here创建你的第一个本地厂库我是在e盘下创建了一个Gitfile的文件目录,你们可以直接Git命令行mkdir，然后cd到目录下，先初始化这文件目录为master,命令:$ git init就能看到此文件目录为master了,可以通过命令查看到隐藏文件,一个名叫.git的文件如果我们使用命令删除.git文件，就会发现Gitfile文件不再是master文件$ rm -rf .git可以通过命令查看.git文件下有许多文件,这些文件代表着你的Gitfile文件是由Git所管理的$ cd .git $ ls -al我们回到上一目录,在Gitfile目录下创建一个名为test.txt文件$ vim test.txt然后在test.txt文件中写入hello world,并使用cat命令查看$ cat test.txt这时候就有个重要命令了,此命令可以查看到Git文件的状态,命令就是:$ git status输入命令后可以查看到:Administrator@8_60 MINGW64 /e/Gitfile (master) $ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) test.txt nothing added to commit but untracked files present (use "git add" to track)这句话翻译过来的意思就是:在master分支上,还有没提交,还未追踪到的文件test.txt,没有任何提交,单出现了未追踪的文件,使用git addgit add这个命令就是,将你工作目录中修改的文件放入到缓存区中,我们使用git add将test.txt放入缓存区$ git add test.txt再次用git status查看Administrator@8_60 MINGW64 /e/Gitfile (master) $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test.txt就已经显示test.txt已经提交到了缓存区,并且也给出了使用git rm --chached命令把test.txt从缓存区删除,放回到工作区,使用命令:$ git rm --cached test.txt再次使用命令查看Git文件状态$ git status接下来我们就要将缓存区里的文件提交到本机的版本库中对于user.name与user.email来说,有3个地方可以设置1./etc/gitconfig(几乎不会使用),命令:$ git config --system2.~/.gitconfig(很常用),命令:$ git config --global3.针对特定项目的,命令:$ git config --local这三条命令的优先级是从低到高,例如我使用第三条命令,再cat /.git/config显示如下:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile/.git (GIT_DIR!) $ cat config [core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true symlinks = false ignorecase = true [user] name = YQHP-YuKi email = ********@qq.com首先是需要记载你的email与提交人的名字$ git config --global user.email "**************@qq.com"$ git config --global user.name "YQHP-YuKi"而git commit这个命令是将你的缓存区里面的所有文件都提交到本机版本库,-m后面加注释,例:Administrator@8_60 MINGW64 /e/Gitfile (master) $ git commit -m "this is my first commit test.txt" [master (root-commit) 3ac93fd] this is my first commit test.txt 1 file changed, 1 insertion(+) create mode 100644 test.txt翻译:一个文件已修改,增加了1行我再次输入git status,发现已经提交成功Administrator@8_60 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean使用git log就可以查看到以往的提交信息了Administrator@8_60 MINGW64 /e/Gitfile (master) $ git log commit 3ac93fdea5963ec35e30f5e116f82bb3e63687e4 (HEAD -> master) Author: YQHP <***********@qq.com> Date: Wed Nov 11 11:56:30 2020 +0800 this is my first commit test.txt注:上方的那一串数字是Git的提交id(commit id),是一个摘要值,这个摘要实际上是一个sha1计算出来的值然后我继续vim test.txt在下方添加I am YQHP-YuKi,再git status:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test.txt这时候显示文件已经被修改,如果你想改回原来的版本,则可以执行命令git checkout -- 文件名,例子:$ git checkout -- test.txt再vim test.txt或者git status又回到了初始状态我们echo一下,继续修改，然后git add,并且git ststus$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test.txt如果我们想把缓存区中修改的文件再放回到工作区,也可以用这个命令git reset HEAD:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git reset HEAD test.txt Unstaged changes after reset: M test.txt相当于git rm --cached两者比较:$ git rm --cached test.txt rm 'test.txt'$ git reset HEAD test.txt Unstaged changes after reset: M test.txt然后继续git add test.txt和git commit -m,并且使用git log查看日志:$ git log commit b079cdb4554f8e1fe04cf4780fe9bc9584dad1d5 (HEAD -> master) Author: YQHP-YuKi <********@qq.com> Date: Wed Nov 11 16:47:11 2020 +0800 This is my test0.2 commit 20bc893146cb23040c5b0b83180be73c7c0bc5d1 Author: YQHP-YuKi <********@qq.com> Date: Wed Nov 11 16:19:53 2020 +0800 This is my test0.1就会发现我们提交的两次版本我们再次创建一个文件名叫test2.txt,并对其进行git add和git commit,然后使用git log对其进行查看A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git log commit e93c2027de92a1faec3902af4a13352dc7347174 (HEAD -> master) Author: YQHP-YuKi <*******@qq.com> Date: Thu Nov 12 15:43:19 2020 +0800 This test is fot Trek commit b079cdb4554f8e1fe04cf4780fe9bc9584dad1d5 Author: YQHP-YuKi <*******@qq.com> Date: Wed Nov 11 16:47:11 2020 +0800 This is my test0.2 commit 20bc893146cb23040c5b0b83180be73c7c0bc5d1 Author: YQHP-YuKi <********@qq.com> Date: Wed Nov 11 16:19:53 2020 +0800 This is my test0.1可以查看到test0.1与test0.2是与test.txt有关的版本注释,而 This test is fot Trek是test2.txt的版本注释,如果我们想删除版本库中的某个版本,可以使用git rm这个命令,例:$ git rm test2.txt$ git status查看到此文件又回到了缓存区要把test.txt放回工作目录,命令git reset HEAD，例:$ git reset HEAD test2.txt要把工作区的文件重新放回到版本库,相当于撤销之前的两次删除操作,命令git checkout --,例:$ git checkout -- test2.txtgit rm与rm的区别:git rm是直接将文件从版本库删除到暂存区:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git rm test2.txt rm 'test2.txt' A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: test2.txt若想回到工作区,则是git reset HEAD:$ git reset HEAD test2.txt Unstaged changes after reset: D test2.txt若想回到版本库,则必须是先回到工作区,才能回到版本库git checkout:$ git checkout -- test2.txt而rm是直接将文件从版本库删除回到工作区,如果想回到版本库,则直接git checkout就能回到版本库:$ git checkout -- test2.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree cleangit mv与mv的区别:git mv将test.txt修改为test3.txt:$ git mv test.txt test3.txt查看状态:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: test.txt -> test3.txt如果想不改名了,还是用test.txt,需要做的操作恢复test.txt并且删除test3.txt:$ git reset HEAD test3.txtA@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: test.txt Untracked files: (use "git add <file>..." to include in what will be committed) test3.txt这时候需要2步操作,1:恢复test.txt,2:删除test3.txt:操作1:$ git reset HEAD test.txt Unstaged changes after reset: D test.txt$ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: test.txt Untracked files: (use "git add <file>..." to include in what will be committed) test3.txt no changes added to commit (use "git add" and/or "git commit -a")A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git checkout -- test.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) test3.txt nothing added to commit but untracked files present (use "git add" to track)现在之剩下还在工作区的test3.txt了,于是进行操作2:A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ rm test3.txt A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git status On branch master nothing to commit, working tree clean如果你想修改test.txt成为test3.txt,则需要两个步骤:步骤1:mv文件名A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git mv test.txt test3.txt步骤2:将暂存区里的test3.txt提交到版本库A@DESKTOP-6DP8MG1 MINGW64 /e/Gitfile (master) $ git commit -m 'change to test3.txt' [master 3b5830c] change to test3.txt 1 file changed, 0 insertions(+), 0 deletions(-) rename test.txt => test3.txt (100%)用git log能够查到改名的记录,ls能查到test.txt文件变为test3.txt并且已删除test.txt,总结:git mv相当于将你源文件从版本库删除出来,并且复制出一个新的名字不同的源文件,再将它提交到版本库mv:直接$ mv test.txt test3.txt$ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: test.txt Untracked files: (use "git add <file>..." to include in what will be committed) test3.txt这时候可以看出来,mv是直接将test.txt变为了test3.txt,但这两个文件却是都没有放入缓存区和版本库的,如果不想改名,则应该像这样test.txt用git checkout --,而test3.txt直接rm:$ git checkout -- test.txt$ rm test3.txt$ git status On branch master nothing to commit, working tree clean如果继续改名,则应该git add两个文件:$ git add test.txt test3.txt$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: test.txt -> test3.txt接下来就git commit --跟操作git mv一样了一次性添加多个文件每个都写很麻烦,可以命令git add .把当前目录下的所有文件都纳入暂存区git commit --amend -m命令修改提交信息例子:$ git commit --amend -m'change again'git log可以带的参数-p展开显示每次提交的内容差异-n仅显示最近的n次更新--stat仅显示简要的增该行数统计--pretty=oneline只显示版本号与版本注释--pretty=format:"%h-%an,%ar:%s"只显示版本号头几个数字、提交者、和距离当前的日期查看git帮助文档两条命令:$ git help config$ git config --help