复习git

git 常用点,详解

from my typora

这一类: git add、git commit 、git push、git status、git init

但是注意第一次初始化本地库,最好用git clone,强调,不要git init git pull。

再补充一下,其实pull = merge + fetch

包括 git config user.name 、git config user.email 以及–global参数。

我就跳过了

保存现场:https://blog.csdn.net/qq_36791569/article/details/82716694

git 模式解析

git中,几大空间,依此的关系,分别是:

工作区 — 暂存区 — 本地库 — 远程库

工作区:就是写代码的地方;

暂存区:是一共中转站,通过git add 到达;

本地库:一个比较稳定的地方了,add之后,通过commit到达。

远程库:通过push、pull进行交互。

其中几种撤销我就略过了:比如工作区修改撤销,暂存区修改撤销,比较鸡肋,有兴趣看这两段话:

https://blog.csdn.net/qq_36791569/article/details/82694577

删除文件

方式一:

rm test.txt 先删除工作区的test.txt 
git add test.txt (我的理解是,将删除test.txt这个动作add上去,告诉本地版本库) 
git commit -m “删除了test.txt”

方式二:

rm test.txt 先删除工作区的test.txt 
git rm text.txt 提交一个git动作,删除本地版本库中的text.txt但是只是记录了动作,还没有commit提交到本地的版本库中 
git commit -m “删除了test.txt”

远程库

# 增
# 添加远程库
# 不一定要叫origin,只是我们习惯叫origin,下同!
git remote add origin https://gitee.com/yaoguai1998/LearnGit.git

# 删
# 删除远程库
# 远程库库名叫什么,就删什么!
git remote rm origin

# 查
# 查看所有远程库的缩略信息
git remote 
# 查看所有远程库的完整信息
git remote -v

# 改
# 改变远程库的url,这里写的是git@为ssh协议,不是http协议,但是均可
git remote set-url origin git@gitee.com:yaoguai1998/LearnGit.git

配置忽略文件

在我们协同的时候,经常因为项目中的一些.class文件,target目录,.project一类类似的文件冲突,这种东西我们要让git去忽略它,不进行同步

  • 首先准备一个忽略文件(*.gitignore)
# Java.gitignore,随便放哪里,我放在用户家目录下的
# Java.gitignore:文件名随便取
# Java.gitignore文件内容如下
# -------------------
# Compiled class file 
*.class

# Log file 
*.log

# BlueJ files 
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/


# Package Files #
*.jar 
*.war 
*.nar 
*.ear 
*.zip
*.tar.gz 
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

.factorypath
.classpath
.project
.settings
target

jdbc.properties
# -------------------
  • 单库方式
# 找到当前本地库文件夹中的.git文件夹
# 打开其中的config文件
# 添加以下内容
[core]
			# 这个是你的gitignore文件的路径,因为我是放家目录的
	excludesfile = C:/Users/Administrator/Java.gitignore
  • 全局方式
# 到用户家目录下,找到.gitconfig文件
# win在 C:Users(用户组)Administrator(当前用户目录) 下
# ubuntu一类linux,在 /home/用户/ 下
# 同样添加以上内容
[core]
			# 这个是你的gitignore文件的路径,因为我是放家目录的
	excludesfile = C:/Users/Administrator/Java.gitignore

查看版本库日志,以及版本回退

git log

# 空格向下翻页,b向上翻页,q退出 
git log # 显示所有日志的所有信息,较多并且较为繁琐 
git log --pretty=oneline # 以较好的格式输出 两个斜杠 
git log --oneline # 显示简略信息 两个斜杠
推荐使用:git reflog 显示简略信息,但是相对于上面直接的 git log –oneline多了一个head移动步数,推荐使用这种:git reflog

# 最推崇的方式:
git log    --graph      --pretty=oneline   --abbrev-commit
查看日志  分支合并图    一行显示       缩减commitId的长度

git log --graph --pretty=oneline --abbrev-commit

版本回退:

# 别记那么多,版本回退就用 git reset --hard 版本号
git reset --hard c17e52f # [c17e52f:是局部索引值]可以回退到特定的版本 

解决冲突

在我们进行分支合并的时候,本地两个分支:

1.切换到我们需要合并的分支上。

2.进行merge操作,如果没有冲突则会直接成功,如果出现冲突,则会:

git 是一个好工具,就是门槛比较高。
<<<<<<< HEAD
这是我在master上add,commit的内容
=======
这是我在mzy上add,commit的内容
>>>>>>> mzy
可以看出git在这种无法自动处理的冲突上,使用了
<<<<<<<
=======
>>>>>>>
进行标识
<<<<<<<HEAD:固定的表示当前HEAD指向的,不一定是master。
=======:用于冲突之间分隔
>>>>>>>:被合并分支名称
内容一定是当前分支在HEAD下,被合并分支在后面。


手动修改这些文件,去掉其中的分隔符号,并且把内容修改成你想要的样子,
再次 git add readme.txt,git commit -m "合并分支mzy,并且解决了冲突"
我们可以让日志显示格式改一改,看到其中的合并步骤:
git log --graph --pretty=oneline --abbrev-commit

*   3b15b8e (HEAD -> master) conflict fixed
|
| * dbee345 (mzy) AND simple
* | b1d6af5 在主分支上进行提交
|/
* fd4ceae 修改了readme.txt文件
* c5687b8 删除test.txt[C
* b71048d 提交test.txt
* 88726c9 提交了readme.txt中的修改
* e4deff9 git change readme.txt add tracks change of files
* 9a3670d add LICENSE to res
* c3e7dc7 加上了GPL
* c17e52f 加上了一些新玩意儿distributed
* 9f6ffb9 第一次提交readme.txt

合并之后,怎么让另一个分支也享受被合并的愉悦呢?(因为我们分支合并只能体现在当前分支,被合并分支不能体现出来)

你应该反过来想,既然已经合并, 为什么不把原来的分支删除了,按照新分支的样子创建一个新的分支呢?在当前分支的基础上?这样不就行了吗?

替换我们常用的直接merge的方式:

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息(即:原来这个分支的做了什么在log中体现不出来)。

为了让我们的版本库更清晰,我们可以使用普通合并方式:

# 普通合并
git merge --no-ff -m "把dev分支上的内容合并到master上,使用普通合并" dev
git merge --no-ff -m "把dev分支上的内容合并到master上,使用普通合并" dev
$ git log --graph --pretty=oneline --abbrev-commit
*   8fc444b (HEAD -> master) merge with no-ff
|
| * 1601be9 (dev) add merge
|/
* 4aa96bc 修改了readme.txt
* 68f4f31 修改LICENSE
*   6653ea8 Merge branch 'yao' into mzy

分支处理

创建分支:

# 如何创建一个本地分支?
# git branch 分支名
# 例如创建一个dev分支
git branch dev
# 注意噢,如果不带参数,就是查看当前有多少分支
$ git branch
  dev
  master
  tb1
* tb2

# 但是以上的方式,只能创建分支,不能切换到创建的分支上
git checkout -b dev # 不仅创建了dev分支,并且切换到了dev分支上

# 如上就引出了,切换分支的命令
# git checkout 分支名
git checkout mzy # 切换到mzy分支上

删除一个本地分支呢?

# 上面讲了创建一个分支 直接:git branch 分支名
# 删除的话,就是git branch -d 分支名
git branch -d dev # 就删除了dev分支
# 注意以上只能删除本地的分支,不能删除和本地库有关的远程库的分支
# 删除远程库的分支的命令,以下会讲

新概念,追踪(track)关系,前引:

在git远程库和本地库中,我们的分支经常是一一对应的,(这种对应可以名字不同),其实他们物理意义上不是一一对应的,只是在我们看来是一一对应的!

为什么呢?

你发现没有,当你推送的时候:

即使本地有一个master,远程有一个master

本地有一个dev,远程有一个dev

你推送的时候,还是通过

push origin master、push origin dev

pull origin master、pull origin dev

但是如果有追踪关系的话,你在当前分支(如dev分支)上

你直接git pull 、git push

git 就会直接帮你pull 或者push 对应到远程库上的分支!

这种关系,我们叫做追踪:

追踪关系有两种使用场景:

**1.当前本地库有一个分支,但是远程库没有 **

2.当前远程库和本地库,都存在这个分支,但是没有关联起来,希望强关联

如果当前git远程库中,没有当前的本地分支(或者要和远程库中的分支建立追踪关系的时候):

# 方式一:
git push --set-upstream origin mzy
# 方式二:
		# 注意在有些场景下我们用:远程仓库名/分支名,代表远程库上的分支 
git branch -u origin/mzy

# 解除追踪关系
git branch --unset-upstream
# 查看是否有追踪关系
git branch -vv
              # 这种就是有追踪关系
  dev    5631865 [origin/dev: ahead 2, behind 3] dev提交
  master cfd7d4e [origin/master] 删è提交
* tb1    6ee4ba4 [origin/tb1] test3上提交
			  # 这种就是没有追踪关系  
  tb2    6ee4ba4 test3上提交
  test1  729034d [origin/test1] test1提交
  test2  d352291 [origin/test2] test2提交
  test3  6ee4ba4 [origin/test3] test3上提交

删除一个本地分支后,并且删除一个远程分支:

# 首先要确定你现在所在的分支不是你要删除的分支!!!不然无法删除
# 首先切换到任意一个非你要删除的分支上
git branch -d tb2 # 删除的参数可以是
git push origin :tb2

如果需要强制覆盖远程的一个分支怎么办?

git push --force origin master
git push -u origin master -f

如果要强制用远程分支覆盖本地的分支怎么办?

 git fetch --all
 			# 注意在有些场景下我们用:远程仓库名/分支名,代表远程库上的分支
 git reset --hard origin/master
 git pull

当你进行pull的时候,远程库告诉你 fatal: refusing to merge unrelated histories

原因是git判定你的远程库和本地库的分支的内容不相干,所以拒绝了你的合并,如果你执意要的话,请:出门右拐执行

git pull origin master --allow-unrelated-histories

协同最好的方式

我们约定的开发方式,请大家遵守:

首先我们有一个稳定版本(master),基于master产生一个开发版(dev),在开发版的基础上,我们衍生出各个开发者各自的分支:huchao、wanglanlin、yangtao …

1.自己的电脑上只能有自己的分支和dev分支,不随便拉别人的分支。

2.每天或者一段时间代码写完之后,记得提交到远程库的自己分支上。

3.在要往dev上合的时候,commit中的信息必须写清楚,修改了什么文件,以及原因;或者增加了什么功能

4.在往远程库的dev上合并新代码的时候,记得群里告知大家去pull远程库的dev,以及尽快合并到自己的分支上,防止版本库堆积。(或:养成经常pull origin dev的习惯)

5.阶段性dev提交的时候(即全部统一的时候:我称为里程碑),我们约定:此刻我会删除当前远程库上的所有除master、dev以外的所有分支,请大家也删除自己本地的个人分支,以当前的dev分支为模板创建一个新的分支。

# 1.每天工作结束,提交代码到远程库的自己分支上
# 在添加了忽略文件的前提下
git add ./*
git commit -m "提交了xxx"
# 如果设置了以上的追踪关系,直接 git push
git push origin mzy(分支名)

# 2.阶段任务完成,增加更新,提交到dev上
# 为了确保无误,先从远程库pull一次
git pull origin dev
# 然后切换到dev分支上,把自己分支的内容合并上去
git checkout dev
git merge mzy
# 没有冲突,直接fast-forward了
# 如果有冲突,则手动合并,参照上
# 合并完成,add commit push
git add ./*
git comit -m "合并到dev,一定要写清楚合并了什么"
git push origin dev

# 然后删除当前的个人分支,参照新的dev,创建个人分支
# 注意一下操作确保是在dev分支上的!
git branch -d mzy # 删除mzy分支
git checkout -b mzy # 按照当前的dev分支建立mzy分支,并切换到mzy分支

# 以上过程稍微显得有点繁琐,但是因为昨天我测试无法跨分支推送,即只能先这样
# 也是我请教师兄之后,告诉我的方法。
# 最初我是向跨分支推送的,因为原来可以,比如直接把mzy -> push origin dev
# 但是不行,大家解决之后,请告诉我,我们一起优化!
# -----------------------------------------------------

最开始我的想法:(但是没有实现,期待大家一起解决)

问题一

我现在在远程库上有master、dev、dev1、dev2。

dev1和dev2是基于dev创建的,我希望他们本地都只存留dev1、dev2这一类的个人分支,合并的时候,先pull origin dev,如果有冲突,在本地merge了,这一步是能够实现;但是当我想要在dev1上向远程dev分支上推的时候就出错了,只能向远程的dev1上推送,不能向远程的dev上推送。即使我使用push origin -u dev -f 也不行,说everthing up to date,难道当远程分支dev1和本地分支dev1建立了关系,就不能跨分支推送了吗?为了印证这个猜想,我unset-upstream 解除了远程分支dev1和本地分支dev1的追踪关系,但是解除之后仍然不能把已经merge了远程分支的dev1推向远程的dev,所以我不知道我的问题出在哪里了?

原文地址:https://www.cnblogs.com/mzywucai/p/11053334.html