认识Git
先基于Windows下的git操作,熟悉了git的基本概念和使用,直接参考这几篇文章:
然后简单看一个在线代码库的大致情况,以GitLab为例,直接参考这篇文章:
一般注意两点即可:
通常我们都会基于SSH协议来让本地仓库和远程仓库交互,所以需要设置SSH秘钥;
在线代码库通常都会提供clone和直接下载的功能,二者有何区别?
采用git clone的项目包含.git目录,这里面有仓库的历史版本信息。
采用下载zip文件的是没有.git版本历史信息的,就是单纯的最新文件,不再归git管理了。
Gerrit
了解下Gerrit:
使用过git的同学,都知道,当我们
git add --> git commit --> git push
之后,你的代码会被直接提交到repo,也就是代码仓库中,就是图中橘红色箭头指示的那样。那么gerrit就是上图中的那只鸟,普通成员的代码是被先push到gerrit服务器上,然后由代码审核人员,就是左上角的integrator在web页面进行代码的审核(review),可以单人审核,也可以邀请其他成员一同审核,当代码审核通过(approve)之后,这次代码才会被提交(submit)到代码仓库(repo)中去。
Linux下Git的安装
对于安装来说,只需要一步即可,那就是
sudo apt install git
如何确认安装成功?
您可以通过运行此命令并收到类似于以下内容的输出来确认您已正确安装 Git:
git --version
如果出现版本信息,说明安装成功。
如果没安装,会出现以下提示
更多参考:
配置SSH Key
要想从远程仓库clone代码,就需要配置SSHKey
该秘钥一开始是没有的,需要在本地生成,然后填到远程仓库中。
直接参考这篇文章:
Linux基础-- Git SSH key生成与配置_linux ssh key 存储-CSDN博客
注意:
上方参考文章里,开头和第一步是查看,还没到配置步骤,说的是已经生成秘钥的情况。
如果还没配置,就需要按照第二步来配置下。
然后cat查看pub秘钥,复制文件内所有内容
如下:
将该文件所有内容都复制粘贴到代码库的对应设置处,粘贴过后会自动识别
Git常用操作
直接参考:
手把手教你入门Git --- Git使用指南(Linux)_linux 用git-CSDN博客
操作分为本地操作以及远程操作。
通常,我们只需要从远程仓库clone代码到本地;然后将本地修改的commit提交,接着再push到远程仓库。
比如:
git clone https://github.com/Adenialzz/learnGit.git
后面的地址就是远程仓库的地址
ssh地址或者http地址
通常情况下,远程操作的第一步,是使用git clone从远程主机克隆一个版本库到本地。
本地修改代码后,每次从本地仓库push到远程仓库之前都要先进行git pull操作,保证push到远程仓库时没有版本冲突。
git常用命令大全
git remote show origin
注意:不执行“git remote show origin”查看状态,而是直接执行“git pull origin”也是可以的,后面这个命令会自动检查,有更新它就会下载更新部分,没有更新也会提示你。
git pull origin
另外,git log和git status都是查看本地仓库的信息。
git log是查看版本提交信息;git status是查看文件提交情况;另外,git diff查看具体细节。
关于初始化init,克隆clone和拉取pull
git clone之前有没有必要git init_如果文件有git仓库,下载后还需要git init 吗-CSDN博客
git初始化与克隆(git init 与 git clone)-菜鸟笔记 (coonote.com)
git pull和git clone都是拉代码,它们有什么区别呢? - 掘金 (juejin.cn)
git clone是拉到本地仓库;git pull是拉到本地工作区。
git pull的用法
git pull时,可以让远程分支和本地的指定分支合并。
git pull 命令 | 菜鸟教程 (runoob.com)
如果不指定,那默认就是和当前所处的分支进行合并。
常规流程,clone-本地修改-(有新文件就需要add)-commit-pull-push?
得申请个自己的github,然后验证下。
待完善。。。
主要的本地操作
改代码之前一定要先备份。
熟悉Linux下git的本地操作。
Git实用教程(三) | Git本地库操作(仓库初始化、提交修改)-腾讯云开发者社区-腾讯云 (tencent.com)
注意,如果是本地从头开始进行git init,可以在初始化时指定主分支名称
git | 指定 git init 的分支名_git init main-CSDN博客
但是,要注意一个问题,那就是从头开始时,git init之后,如果用git branch查看分支,会发现没有任何分支,并且,如果试图强行建立一个分支,也会报错:
Git 新建分支出现报错:“fatal: Not a valid object name: ‘master‘.“_idea 新建git分支报错-CSDN博客
这是因为主分支也要有一次完整的commit之后才会生成,具体参考上述文章。
注意,git commit时如果没有写评论,会弹出窗口让你填,下面的提示是操作,^这个符号表示ctrl,别搞蒙了。
没有branch的情况下,很多git操作就没法操作,比如刚拉下来的代码,还没有提交过的话,一般是没有本地分支的。
如果没添加到暂存区就提交,会报错
提示修改没在暂存区用于提交。
分支的查看和创建
Git详细教程(五):查看分支、创建分支、合并分支_git 查看所有分支-CSDN博客
分支的合并 git merge
git merge合并,肯定是合并两个分支。
其实,每个人的本地仓库相对远程仓库来说,都是一个本地分支。
如果两个相同的文件在同一个目录下,正常情况肯定是不允许的,但是在git管理下,可以处于不同的分支,然后通过合并可以成为一个完整的项目。
合并后,只会剩下一个分支,要留下哪个,就切到哪个分支下,然后执行合并操作,合并另外一个分支到当前的分支。
更多参考:
彻底理解git 本地分支与远程分支,以及git pull与git fetch的区别, 以及git status输出的“Your branch is behind xxx”-CSDN博客
弄明白如下信息:如果从当前分支A基础上创建一个分支B,那么,B的内容和A的内容在一开始时是一样的,之后,各自更改各自的内容,对方都是不可见的;直到合并两个分支,两个分支的内容才合在一起成为一个文件。
进行分支操作时,发现一个问题,基于master分支创建了dev分支,然后来回切换,在各自的分支上修改,发现不管怎么切换,两个分支的内容都能被两个分支所看见,也就是说,分支是切换了,但是内容竟然是一样的。啥情况?
百度了下
git修改一个分支的内容其他分支也同步被修改_git在当前分支上的修改是否会影响另一个分支-CSDN博客
git切换分支时,该分支的修改被带到另一个分支_git,在本地一个分支上修改了一点点东西,切换到另外一个分支,为什么会自动合并-CSDN博客
重点就是:
每次切换分支之前,都要commit一下。
git匿名分支
Git实用教程 7.2:匿名分支_你有1个未连接到任何分支的分离提交-CSDN博客
git branch HEAD~可以切换到匿名分支;
切换到匿名分支后,就可以删除其他所有的分支了
之后,使用git branch时,就只能看到匿名分支了
git无分支
要和这种情况作区分:
Git 分支 (no branch)|极客笔记 (deepinout.com)
如果你在 “(no branch)” 状态下继续提交,这些提交将会以匿名分支保存,但你可能很难回到这些提交。
Git 分支 (无分支)|极客教程 (geek-docs.com)
其实就是,没有分支时,最好自行创建一个分支或者几个分支。谨慎对待匿名分支或者无分支状态。
repo无分支
repo sync同步后,repo branch和所有仓库执行git branch 都显示no branches
【git】repo init和sync下载代码后,没有指定分支,后面push产生冲突的惨痛解决_repo sync 指定分支-CSDN博客
无branch,后续必须执行repo start 分支名 --all 建分支才能开发,比如:
repo建立的分支会应用到其管理的所有的仓库,然后,各仓库也能独立地创建仓库,比如repo branch显示如下:
当服务器有新的更新后,直接repo sync就可以同步了
git删除分支
Git 删除分支——如何删除本地或远程分支_git 删除本地分支-CSDN博客
git branch -d 分支名
我们刚刚使用的删除本地分支的命令并非在所有情况下都有效。
如果分支包含未合并的更改和未推送的提交,则该-d标志将不允许删除本地分支。
这是因为任何其他分支都看不到提交,并且 Git 正在保护您免于意外丢失任何提交数据。
如果你尝试这样做,Git 会显示一个错误:
正如错误所暗示的那样,您需要改用该-D标志:
git branch -D local_branch_name
-D带有大写-- delete --force字母D(它是 的别名)的标志会强行删除本地分支,无论其合并状态如何。
但请注意,您应该谨慎使用此命令,因为没有提示要求您确认您的操作。
仅当您绝对确定要删除本地分支时才使用它。
如果您没有将其合并到另一个本地分支或将其推送到代码库中的远程分支,您将面临丢失所做的任何更改的风险。
关于冲突出现的时机:
Git pull的时候,会先fetch,然后再merge,fetch一般不会有问题,主要是merge的时候可能会出现冲突。
那什么时候会出现merge呢?主要有三种情况:
因为pull是直接pull到工作区,所以,当直接pull的时候,如果本地和远程都修改了同一份文件,本地文件如果没有加入暂存区或者提交,就会在工作区merge的时候发生冲突;
如果本地已经加到暂存区了,那么pull的时候不会提示冲突,但是,把本地暂存区的内容释放出来,然后在工作区merge的时候,就会产生冲突;
如果本地的内容已经commit提交了,那么pull的时候也不会产生冲突,但是,当再次提交时,因为待提交的内容和已提交的内容有冲突,此时的merge也会产生冲突;
也就是说,只要修改了同一份文件,就会产生冲突,只是在什么时候merge,就什么时候发生冲突,这种情况,冲突必然会发生,只是发生的时机不一样。
直接pull时,产生冲突,会导致pull失败;本地提交,然后再pull,会导致本地有很多提交颗粒;建议使用第二种,pull之前,先stash本地,然后pull完成之后,再解决冲突,这样,既能成功pull,还可以减少提交的颗粒。
注意:解决冲突后,正常add和commit即可。
git stash解决git pull和本地文件的冲突_git stash git pull-CSDN博客
别忘了提交完成后,删除stash。
总之,上述的过程的关键是要知道有三种空间,提交的仓库、暂存区、工作区。
注意,加入到stash后,git status就看不到状态了,因为git status看的是工作区的状态信息。
注意:先commit再pull有个好处就是,如果pull或者修改的内容要回退,可以直接回退到某个commit版本,但是另外两种方式就不行了。虽然提交的颗粒度较多,但是和安全性相比,就显得不那么重要了。
本人建议先commit然后再pull,这种情况,其实工作区的变动就相当于是新的修改,我们可以下次再提交。
解决冲突
合并不同的文件是没什么问题,如果多个分支修改了同一个文件,当合并时就会出现冲突。
详情参考:
一般,从云拉到本地,HEAD里面是本地的内容,后面的是云端的内容。
需要先解决这些冲突才能执行其他操作,可以执行git merge --abort退出合并的中间状态
注意,解决冲突后的文件就相当于处于工作区的一个新文件,按照常规来执行add和commit,就可以了。
解决冲突之后git add和git commit,但还是有问题
git status查看,提示如下:
interactive rebase in progress; onto 796e78f
解决如下:
git rebase参考:
Git回退到某个版本
git diff
git diff 版本号1 版本号2 --stat
加了--stat可以只看摘录,也就是改动了哪些文件,不看文件的改动细节。
其他一些常用的命令
git add
git commit
git branch
git fetch
等等。。。
更多参考:
git的配置文件
要验证本地仓库的Git设置,请使用以下命令: git config –list
Git提供了git config工具,允许您设置配置变量。Git将所有全局配置存储在位于您的主目录中的.gitconfig文件中。要将这些配置值设置为全局变量,请添加–global选项,如果省略–global选项,则您的配置将仅适用于当前的Git仓库。
您还可以设置系统范围的配置。Git将这些值存储在/etc/gitconfig文件中,该文件包含系统上每个用户和仓库的配置。要设置这些值,您必须具有root权限并使用–system选项。
repo工具
除了使用git,我们还可以使用repo工具来管理仓库,进行仓库的初始化和同步。
Git、Gerrit、Repo三者的区别及使用_gerrit repo-CSDN博客
使用sudo apt-get install repo 命令直接安装
repo可以看做是对git的封装。
常用操作参考以下文章:
使用示例:
补充:
repo init会初始化一个.repo仓库管理文件
repo是多个git的管理,一种应用场景是,整个工程用repo来管理,然后工程里面的各个文件夹都用git管理。
不提交git就没有版本信息,就没法回退。改完想要再改回来就很麻烦。
如果改完后有问题,难道再一个地方一个地方地去改吗?显然是不可行的。
repo sync ##默认同步所有仓,可以指定project 。
如果是第一次运行 repo sync ,则相当于 git clone,会把server所有内容都拷贝到本地。根据manifests中的xml文件中git的commit进行同步,这个xml文件在repo init的时候指定;
如果不是第一次运行 repo sync ,则相当于 git remote update ; git rebase origin/branch 将server上的code与本地合并;如果在rebase 的过程中出现冲突,这需要手动解决冲突,然后运行:git rebase --continue
非初次运行repo sync时,会有如下操作:
Git fetch 和 git checkout 与仅执行 git checkout 的区别|极客教程 (geek-docs.com)
git pull好像是git fetch和git merge的综合操作,和repo sync略有区别。
Git 合并和切换命令的介绍|极客教程 (geek-docs.com)
反应底层都会拉代码以及合并,就不要过分纠结了。
避免冲突的根本方法:
明确分工,相同文件,尽可能只由一个人操作 (根本上解决问题)
注意,repo init只是初始化一个.repo,并不能下载程序,下载程序需要repo sync,别搞错了。。。。。。
XML和manifest文件
XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。XML 是一种可扩展标记语言,用于描述数据的结构,而不是显示数据。XML 文件以 .xml 扩展名存储,可以用不同的方式打开,如本地浏览器或在线查看器。XML 标签没有预定义,可以根据需要自行定义。
在repo仓库管理中,通常就是用manifest的xml文件来描述目录结构
参考:
一张图让你掌握清单文件manifest.xml的重点_repo project-objects-CSDN博客
注意,是manifest,不是main....
补充
怎么看diff文件?
diff命令--输出格式解读_diff format-CSDN博客
从实用角度出发看懂和使用diff、git diff的合并格式 (lksr.net)
读懂diff(转载) - michael111 - 博客园 (cnblogs.com)
重点关注git格式的合并diff,主要是在第三篇参考文章的最后一小节讲到了。
其实,只用看文件和加减的地方即可。
git打补丁patch
Git版本控制中的补丁(patch)是什么|极客教程 (geek-docs.com)
注意,如果补丁本身还没有被提交,是不能被下载的。
很多时候,不想让某些文件参与到git的管理之中,可以将这些文件类型加到一个.gitignore文件中
.gitignore 文件——如何在 Git 中忽略文件和文件夹详细教程-CSDN博客
但是要注意,如果你发现加了之后还没什么效果
【问题分析解决】git添加.gitignore后不生效问题_gitignore文件不生效-CSDN博客
很有可能是你加入的一些文件在之前就已经被git进行track跟踪了,此时,可以先将这些文件从跟踪列表中移除
在git是用过程中,可能遇到以下情况:
1、被跟踪文件里面有不想跟踪的文件。
2、每次用git status查看状态时总是列出未被跟踪的文件。
解决方法:
1、当被跟踪的文件里面有不想跟踪的文件时,使用命令git rm删除文件。如:
git rm --cached readme1.txt 删除readme1.txt的跟踪,并保留在本地。
git rm --f readme1.txt 删除readme1.txt的跟踪,并且删除本地文件。
然后git commit即可。但是git status查看状态时还是会列出来。
2、每次用git status查看状态时总是列出未被跟踪的文件,可以通过.gitignore文件达到目的。
也就是git add的反向操作。
注意,移除之后,要执行一次git commit来使其生效。
先pull还是先commit
Git commit与pull的先后顺序_git先pull再commit-CSDN博客
一般是先pull,再commit,再push
如果先pull再commit,则pull时可能会出现冲突,需要先解决冲突。
不过,先commi再pull,至少可以保证自己的代码不会丢失,而先pull再commit,有可能导致自己的代码丢失。我推荐先commit再pull。
git cherry-pick
想在某个稳定版本上,添加一个刚开发完成的版本中的功能。就可以使用 Cherry-pick 命令,将这个功能相关的 commit 提取出来,合入稳定版本的分支上。
对于多分支的代码库,将代码从一个分支转移到另一个分支是常见需求。
通常开发时分两种情况:
需要将某一个分支的所有代码变动,那么就采用合并(git merge)
只需要某一个分支的部分代码变动(某几个提交),这时可以采用 Cherry pick
cherry-pick 和它的名称翻译一样,精心挑选,挑选一个我们需要的 commit 进行操作。它可以将在其他分支上的 commit 修改,移植到当前的分支。
git cherry-pick命令的作用,就是将指定的提交(commit)应用于其他分支。
git cherry-pick <commitHash>
上面命令会将指定提交的commitHash应用于当前分支。此时在当前分支产生一个新的提交,新提交代码的哈希值会和之前的不一样。
git config命令
【git问题】couldn‘t find remote ref
【git问题】couldn‘t find remote ref_couldn't find remote ref-CSDN博客
git放弃当前的修改
git放弃本地文件修改 - 简书 (jianshu.com)
放弃修改是相对最近一次提交来说的。
建议每次新增功能,都新建一个开发分支,如果开发没问题再合入到主分支上。
要不然修改了,然后要恢复,很麻烦。省得老是整个复制代码去备份,而且容易出现问题,比如路径更改引起的问题。
通常,本地操作时,在某个分支上开发完功能,再合入到master时,不会有冲突,因为开始时分支就是基于master的,只要master没改动,就不会有冲突,仔细体会下。
不建议一次性add所有文件,而是一个一个地add,然后再commit,要不然一些过程文件被加进去,然后又在.gitignore里不好屏蔽,就容易干扰正常的开发。事实上,哪些文件有改动,我们都是知道的。所以,建议手动添加文件。
windows和ubuntu下git commit提交后如何保存和退出,回到命令行 - wuguoxing - 博客园 (cnblogs.com)
注意:repo下各git仓库可以独立操作。也有一些操作可以repo直接针对所有的仓库。
一个很重要的概念,那就是repo可以用来管理多个仓库,其实所谓的多个仓库,就是多个git仓库,repo可以通过manifest文件来指定仓库的目录结构分布以及所属的远程分支等信息。
每个repo管理有一个.repo文件,只在最上层;
每个仓库有一个.git文件;有时候,我们可以看到一个.git所在的目录下面还有.git,这种情况下,每一层的.git其实只负责当前目录层的git管理,是看不到其他层git的变化情况的。如果到了某一层,再往下就没有.git了,那么这个最下层的.git就负责其下所有文件的git管理。所以,有时候,你发现明明改动了一些文件,然后git status或者git diff却发现没有任何变化,那是因为你没有在对应的.git层来操作;或者有时候,你拉了一些代码下来,发现只提示部分文件没有commit,明明你还修改了其他的文件,那是因为,你拉的代码是属于其中某一个仓库的,所以,只会提示跟该仓库有关的内容的改变。也就是说,如果只是针对某个仓库做的改变,可以不必repo sync来同步所有的仓库,而只用在对应的仓库下进行git pull即可。
总之,细细体会一番。
无分支或者匿名分支切换到正常分支之后,原来无分支或者匿名分支状态下的修改全没了。所以,repo拉下来之后建议第一时间就repo start,然后再开发。