Git 命令行操作

全文结构:


1)仓库概念

首先从总体上看,git的存储、操作:

 

主要涉及到四个关键点:

  1. 工作区(workspace):本地电脑存放项目文件的地方,比如learnGitProject文件夹;
  2. 暂存区(Index/Stage):在使用git管理项目文件的时候,其本地的项目文件会多出一个.git的文件夹,将这个.git文件夹称之为版本库。其中.git文件夹中包含了两个部分,一个是暂存区(Index或者Stage),顾名思义就是暂时存放文件的地方,通常使用add命令将工作区的文件添加到暂存区里;
  3. 本地仓库(Repository):.git文件夹里还包括git自动创建的master分支,并且将HEAD指针指向master分支。使用commit命令可以将暂存区中的文件添加到本地仓库中;
  4. 远程仓库(Remote):不是在本地仓库中,项目代码在远程git服务器上,比如项目放在github上,就是一个远程仓库,通常使用clone命令将远程仓库拷贝到本地仓库中,开发后推送到远程仓库中即可; 

2)分支概念

1)分支介绍:

  • develop 分支(唯一):用于平时开发的主分支,并一直存在,永远是功能 最新 最全的分支。
    • feature分支(N个):用于开发新的功能的分支,一般是多个员工一人一个feature远程分支。
    • release分支:用于发布准备的专门分支。
  • master 分支(唯一):最为稳定、随时可发布的代码;所有在 master 上的提交都必要要有 tag ,方便回滚。
    • hotfix分支:用于修复线上代码的 bug

2)分支关系:

develop和master是2个主要分支,这两个都是唯一的

其他的3种分支都是从这2个分支派生出来的:

  feature从develop拉出,并回到develop

  release从develop拉出,并推送到develop+master两个分支(保证同步)

  hotfix从master拉出,并推送到develop+master两个分支(保证同步)

3)特性总结:

生命周期:

  feature和hotfix是临时的

  其他3个都是长期存在

直接开发:

  从不:master、release

  不建议:develop

  直接:feature、hotfix(和临时对应)


一、基础流程

首次需:

0. git init  初始化新仓库(init 好像没啥用)

1. 到代码文件夹,右击 Git Bash Here,打开到本文件路径

2. git clone + GitHub网页上Repository复制下来的 URL

3. 此时是远程分支是origin/master(origin层次下的master分支);本地分支是默认的master;需要切换远程分支和本地分支:

  git checkout -b  jqy-local-dev(本地分支名)origin/dev(远程分支名)

(如果没有这一步的操作,就会从master拉取,因为SSH的url只有一个)

3.1先用 git branch -a 查看所有本地+远程分支

 3.2 切换分支

  注意上图中本地分支已经切换,origin/dev是根据需要选择的远程分支,远程分支改变后,本地文件会由origin/master这个远程分支变为你选择的远程分支

 (ps: 将本地分支和远程分支关联的操作一般只用于拉取的时候,而后面就不用管这个关联了,因为git push origin jqy 这个指令一般不用,都不会原路推到代码来源如dev远程分支,而是push到自己的远程分支,然后MR等待评审再合并到需要的分支)

后续:

不断编码修改...

4. cd到新文件夹中,Git Bash

5. git add .   (注意" . "不能省略,此操作是把文件夹下面新的文件或修改过的文件添加进来,如果有的文件之前已经添加了,它会自动省略)

6. git commit  -m  "提交信息" (提交的信息是你的项目说明)

7.(配置好用户名、邮箱)

8. git push origin master   

    git push [remote-name] [branch-name]

(此操作目的是把本地仓库push到github上面,此步骤需要你输入登录github上的帐号和密码)

(一般团队开发都用 git push origin jqy:jqy001这样推到自己的远程分支,然后提交MR;而不是直接push就完事)

git push origin jqy:jqy001 本地分支提交到远程分支

(9.) 如果push的时候显示冲突(有人改了对应的远程分支),就先pull一下:

git pull origin jqy001

对比冲突,解决后再push

10. 然后在网页中Submit MR,比如从jqy001==>dev

等待代码审核即可...

二、分支管理

git branch  查看本地分支; 

git branch -a  查看所有分支(包括远程

 

上方是本地分支区,下方origin一堆是远程分支;箭头指向的是当前本地分支、远程分支


 git checkout -b [branchname]    创建+切换 分支

  • git branch dev   创建分支(这个一般用不上)
  • git checkout dev   切换分支(此处的dev可以为git reflog的七位数字)

git branch -d [local-branch-name]    删除分支(本地)

git branch -r -d [remote-branch-name]    删除(远程remote)分支


 修复上一个版本的bug:

1. git log找到bug版本的版本号 

2.git branch 1db3731将HEAD移动到bug版本

3.git branch -b myfixbug然后开始在此分支修改bug 

4.等到master里面到下一个版本上线之前,合并myfixbug

最好看着IDEA中的版本线状图===》》》

顺便学习Github/CodeHub团队开发策略(分支策略)总结下来


  • git push origin master  //push到origin的master分支
  • git push origin dev  //push到origin的dev分支

git remote -v   查看连接SSH的url   (远程库的默认名称是origin


 git branch -v  

git branch -vv   

显示local分支对应的远程分支


 设置origin:

三、团队开发 - MR提交

在团队合作软件开发方面,一般有master分支和develop分支,

开发者先发送merge request请求到develop上,然后通过 项目管理者review之后,才会merge到master分支上。


 Merge Request

(建议在IDEA里面进行,因为方便对照修改的内容):

git branch -b jqy 建自己的本地分支

git add 需要修改的文件(最好不要用git add . 因为这样会add上一些无用的东西)

git commit (提交到自己的本地)

git pull origin jqy001 (与origin中jqy001这个远程分支进行对比,修复冲突,并提交需要上线的文件)

git push origin jqy:jqy001 本地分支提交到远程分支

成功的话,然后在网页中Submit MR

(然后就会由管理员审核MR并提交UAT测试环境。。)


 Merge Request(这种方法一般在push的时候会被卡主)

1) git checkout -b xxx (xxx是新建分支的名字,如feature_i)

2) git add .       git commit -m "..."       git push origin xxx   //在自己的xxx分支的操作

3.1) git checkout master      git merge xxx     git push origin master //切换到master进行合并【命令行版】

3.2) (一定确保第2步有git push origin xxx)然后在gitlab界面进行merge request的信息填写 【GUI版,适用于代码审核】

四、解决冲突

git merge dev       // 一般将dev分支的修改merge到master分支上

merge的时候,如果有同时修改的内容, 就发生冲突(此时无法自动merge),需要查看conflict然后手动合并。


 一开始两个不同的分支同时修改master的readme文件:

第一个merge的不会出问题,

第二个merge时候:

 

 在 git merge feature_1之后,查看feature_1的文件,会显示比对信息:

手动修改readme文件(不用切换到feature_1分支),

然后在master分支上面,add+commit 

 然后直接 git push origin master就好了(可以在gitlab 网页GUI上面直接看一下验证):

 


 【另一种方式push】

第二个push出现冲突时:

然后git pull

修改、git add、git commit

然后再push就好

五、回退版本(时光穿梭机)

git status   查看工作目录、暂存区的状态

git diff    查看修改内容  (Git跟踪并管理的是文件的修改,而非文件本身)

  git diff 详细命令: https://www.jianshu.com/p/80542dc3164e

git log   查看日志(一次次commit修改情况,注意是以commit为粒度)

   (git log -p  可看到具体修改内容。按Enter向下阅读)


1)已经commit之后

  • git reset --hard HEAD~1  回退1个提交(彻底回退,冲掉回退的信息)
  • git reset --soft HEAD~1  回退1个提交+保留代码修改信息
  • git reset --hard d311cd2  ==》先用git reflog 查看各个版本的 commit id(如d311cd2)进行自由回退  (很好用!)

 2)已经add,但没有commit(错误还在 stage暂存区)

两步操作:

git reset HEAD [filename]       

git checkout -- [filename]  

 3)还没有add(错误还在 工作区)

只需要一步:

git checkout -- [filename]

(这样操作的粒度比较小;reset的话,粒度比较大;因为一般是一次commit是一到多次add的总和)


分析下粒度:

多次add,一次commit;

多次commit,一次push;

所以:

commit后的reset --hard 序号《==》1~n次的commit的粒度

add后的reset HEAD《==》回退到上次commit后的状态,相当于1~n次的add的粒度

add前的 checkout -- [filename] 《==》回退到上次add后的状态,相当于1次add内的粒度


详细说明git reset:

 git reset --hard HEAD^   硬回退一步

(此时本地回退了,但是远程没有回退;如果需要远程也回退,就要git push origin xxx再提交一下)

git reflog 查看各个版本的 commit id(如d311cd2)

git reset --hard d311cd2  根据后面的commit -m "..."信息,找到对应的id,进行自由回退  (很好用!)

 

六、忽略文件  .gitignore

1)规则

/   //表示目录

*  //匹配 任意个字符

?  //匹配 一个字符

[ ]  // 正则匹配 一个字符

!  //表示忽略匹配

2)示例

# 此为注释 – 将被 Git 忽略

*.log    #表示所有的 .log文件(也包括子目录里的)
*.iml    *.ipr    *.iws
*.txt       # 忽略所有 .txt 结尾的文件
!Readme.txt    # 但 Readme.txt 除外

/TODO     # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/node_modules

hello[0-9].txt
.settings/   # 忽略settings文件里的全部
.idea/   .vscode/   target/   .gradle   /config
build/    # 忽略 build/ 目录下的所有文件
doc/*.txt    # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

/fd1/*    #忽略根目录下的 /fd1/ 目录的全部内容;
fd1/*    #忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;

   


  想把某些目录或文件加入忽略规则,按照上述方法定义后发现并未生效,原因是.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:

git rm -r --cached .
git add .
git commit -m 'update .gitignore'


PS:理解CRLF / LF

  • CRLF  回车换行    Windows 换行方式  CRLF== carriage return line feed 
  • LF  换行    Linux&Unix 换行方式  LF== line feed

  本来在自己的 Ubuntu 系统上跑的很好,觉得没bug就提交了。然而,同事使用的是Windows系统,他编译之后怎么跑都不正常。
在Windows系统上换行符是CRLF, 两个字符,只删除 是不够的。所以在读取文件的时候一定要小心跨平台。

Git 提供了一个名为 core.autocrlf 的配置,可以自动完成标准化与转换。它的设置方式如下:
git config --global core.autocrlf  [true | input | false]  # 全局设置
git config --local core.autocrlf  [true | input | false] # 针对本项目设置
  • true:CRLF <=> LF
  • input:CRLF => LF
  • false:不变

注意:

  1. CRLF 与 LF 混合的文本文件不受此配置控制。
  2. Git 安装后默认为 false

使用 Windows 系统的开发者设置:
git config --global core.autocrlf true

使用 Linux/MacOS 的开发者设置:

git config --global core.autocrlf input

 ps:IDEA界面化Git操作

更多内容参见:《Git -- IDEA界面操作》

    

命令行操作是git的根基,在此基础上的 IDEA界面操作,功能更加可视化、易于理解。


参考   git使用教程(有详细实例): https://zhuanlan.zhihu.com/p/30044692 

     git基本操作(精简手册):https://juejin.im/post/6844903598522908686

     廖雪峰git:https://www.liaoxuefeng.com/wiki/896043488029600

最后去练习吧:https://learngitbranching.js.org/?locale=zh_CN

原文地址:https://www.cnblogs.com/qyf2199/p/13190654.html