Git基础命令

git原理:
git pull和 git fetch原理区别
git官网教程

参考链接 基础git提交命令详解
参考链接 git 远程仓库回滚解决方案
参考链接 生成ssh key
基础操作

文章目录


一 、概念理解

1. 合并原理:

1.1 快进

在合并的时候,你应该注意到了“快进(fast-forward)”这个词。 由于你想要合并的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后继, 因此 Git 会直接将指针向前移动。换句话说,当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”
例如: master分支 dev分支基于master创建 此时合并是“快进”方式合并 反之 “commit提交不同步”合并

1.2不同步合并

方式 :你在 hotfix 分支上所做的工作并没有包含到 iss53 分支中。 如果你需要拉取 hotfix 所做的修改,你可以使用 git merge master 命令将 master 分支合并入 iss53 分支,或者你也可以等到 iss53 分支完成其使命,再将其合并回 master 分支。
这和你之前合并 hotfix 分支的时候看起来有一点不一样。 在这种情况下,你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并。
和之前将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交

1.3合并冲突

冲突的产生是因为在合并的时候,不同分支修改了相同的位置。所以在合并的时候git不知道那个到底是你想保留的,所以就提出疑问(冲突提醒)让你自己手动选择想要保留的内容,从而解决冲突

2.git flow git架构流

master分支是 上线分支 也叫(主分支)
develop是开发分支 用于开发阶段的分支
develop的子分支是他的功能分支 feature子分支集 (用于不同功能版本的项目,最后合并到的develop分支上)
release 分支是 预发布版本分支,项目上线之前的预发布版本分支。
hotfixes 分支是 警告分支 ,在项目出现问题的时候 ,或者bug紧急修改时用的分支。

二、基础操作

1.向本地拉取代码

git clone 链接地址 或者(远程分支地址)

地址 : git@ssh.dev.azure.com:v3/4112367460485/Bayer_PH_Train_service/Bayer_PH_Train_service

2.切换分支 把远程分支指向本地分支,跟本地分支同步。

 git branch -b 本地分支名 origin/远程分支名  

查看电脑B本地仓库的分支

git branch

查看本地和远程仓库的所有分支

git branch -a 

把新建的本地分支push到远程服务器,远程分支与本地分支同名

git push origin localbranch:localbranch

在这里插入图片描述

查看远程仓库的分支

git branch -r

(在本地创建一个分支并且与远程分支关联起来,尽量本地名要和远程分支名相同;不过本地分支名可以随便起没关系)

然后 直接 git add . 添加到暂存区 git commit -m ‘标题’ 提交代码
git push 直接 推送到远程仓库
或者

git checkout -b haoyacong_test   //在本地创建一个新的本地分支 
git push --set-upstream origin haoyacong_test  然后 把本地分支提交到远程分支

如果遇到切换远程分支,出现本地文件迁出覆盖的错误提示。 有两种方式 :1.git commit 提交到暂存区 或 git stash 缓存当前本地代码
相关切换分支教程

3.git pull 拉取更新代码

git pull origin next:master 要取回origin主机的next分支,与本地的master分支合并,需要写成这样
git pull origin next 如果远程分支(next)要与当前分支合并,则冒号后面的部分可以省略。可以写成这样

如果遇到以下错误 : Git :fatal: refusing to merge unrelated histories
**错误原因: 是两个分支是两个不同的版本,具有不同的提交历史**
解决方案 : git pull origin master --allow-unrelated-histories 
注解 : 可以允许不相关历史提,强制合并,确实解决了这个问题,感谢网友
合并时,可能会有冲突,解决冲突后。重新 add, commit 提交。

在这里插入图片描述

4. 搭建跟远程连接的地址 git add

git remote add origin git@gitlab.bayer.com:rad-device-service/device-service-phase1.git  -- origin  代表是自定义的远程连接名
git@gitlab.bayer.com:rad-device-service/device-service-phase1.git  : 是git地址

搭建好add的远程地址后
git commit -m ‘名字’
git push -u origin 分支名
即可成功

一般提交git push 之前有两种方式 一种是 git clone 之后 使用 切换到远程分支的方式 与远程分支同步,可直接git push 另外一种是 这种方式 git remote add 建立推送连接 再提交

5. 基于master 创建新的feature分支

git checkout -b 新分支名 老分支名 --这样就在本地创建了一个基于master的feature分支了
git push origin localbranch:localbranch  --将本地创建的新分支 推送到远程仓库去。
git checkout -b 新分支名 --新建本地分支

6.ignore规则

gitignore只能忽略那些原来没有被追踪的文件
如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的
解决方法就是先把本地缓存删除(改变成未被追踪状态),然后再提交

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

6.1 检查文件是否被忽略

如果打印出文件名 代表此文件已被ignore忽略了

git check-ignore [options] pathname # 路径/文件名

7.git 合并分支

参考链接: 戳这里
例如: feature合并到develop
就需要切换到develop分支

  git merge  feature    --或者  feature  要合并的分支
  git merge  feature      --allow-unrelated-histories

执行 git merge feature 或者 git merge feature --allow-unrelated-histories
最后 本地合并好了 ,还需要 git push 推送到远程仓库。
合并develop到master也是一样 ,切换到master
执行 git merge develop 或者 git merge develop --allow-unrelated-histories
最后 再 git push。

合并的时候,记得本地缓存区不能有文件。

如果合并的时候 出现 文件冲突的话,就用vs 打开 项目的团队资源管理器 查看冲突文件解决就行 或者打开 vs code 也可以 查看 冲突文件.(vs工具更好点)

7.1 合并分支生成一次新的commit

git merge --no-ff -m "merge bug001" bug001

–no-ff参数,表示禁用Fast Forward模式,禁用后Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

8 更新远程分支列表

git remote update origin --prune

三、其他问题

1.提交时出现中文文件乱码

解决 文件名中文乱码 : git config --global core.quotepath false
文档:https://blog.csdn.net/u012145252/article/details/81775362

2. 提交到远程仓库时遇到以下错误:

在这里插入图片描述

2.1 场景 一

原因: 你本地git的账户和邮箱 与 远程仓库的所有者邮箱不一致。
解决方案: 配置远程仓库的所有者的邮箱与本地一致即可。

2.2 场景二

原因:分支中包含多个人的提交记录,这时你提交的时候出现用户不一致
解决方案:
1 . github提供git脚本可以批量修改仓库中的所有提交记录的用户和邮箱信息。
2. 也可以修改单个提交记录的提交用户信息。

2.2.1 批量操作

批量操作会修改仓库中的所有提交 (请谨慎使用)
将此脚本放至.git根目录下

#!/bin/sh
 
git filter-branch --env-filter '
OLD_EMAIL="原来的邮箱"
CORRECT_NAME="新用户名"
CORRECT_EMAIL="新用户邮箱"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
# 最后执行sh脚本就可以了
./test.sh

2.2.2 修改最近一条提交信息

git commit --amend --author='名称 <邮箱>'

2.2.3 修改指定提交记录信息

戳这里

3. 注意在ubuntu上面拉取git 仓库代码

一定要在ubuntu用户权限下 不要用sudo 去拉代码 使用 sudo 会吧本机的服务器登录 ssh秘钥做git验证的。

四、保存与变更

1. 删除分支

删除本地 分支 :git branch -d 分支名
(注意 :删除本地分支的时候,一定要切换到别的分支。去删除。不要在当前分支删除当前分支。)

git push origin --delete dbg_lichen_star  --删除远程仓库分支 origin: 代表 远程连接名

或者

git push origin :dbg_lichen_star --推送一个空分支到远程分支,其实就相当于删除远程分支:

2 .保存工作现场

git stash

备份当前工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同事,将当前的工作区内容保存到Git栈中。

git stash pop

从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。

git stash list

显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。

git stash clear

清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。

五、代码仓库状态(查看与校验)

1. git diff 检查和比较差异文件

1.1 比较两次commit提交之后的差异:

 git diff hash1 hash2 --stat

1.2. 具体查看两次commit提交之后某文件的差异:

 git diff hash1 hash2 -- 文件名

1.3. 比较两个分支的所有有差异的文件的详细差异:

  git diff branch1 branch2

1.4. 比较两个分支的指定文件的详细差异

   git diff branch1 branch2 文件名(带路径)
   git diff master origin/master (对比本地与远程分支)

1.5. 比较两个分支的所有有差异的文件列表

git diff branch1 branch2 --stat

2. Tag 标签

2.1 创建标签

创建 tag 是基于本地分支的 commit,而且与分支的推送是两回事,就是说分支已经推送到远程了,但是你的 tag 并没有,如果把 tag 推送到远程分支上,需要另外执行 tag 的推送命令。

git tag <tagName> //创建本地tag
git push origin <tagName> //推送到远程仓库
git push origin --tags
//若存在很多未推送的本地标签,你想一次全部推送的话

以上是基于本地当前分支的最后的一个commit 创建的 tag ,但是如果不想以最后一个,只想以某一个特定的提交为tag ,也是可以的,只要你知道commit 的id。

git tag -a <tagName> <commitId>

2.2 查看tag

查看本地某个 tag 的详细信息:

git show <tagName>

查看本地所有 tag:

git tag 或者 git tag -l

查看远程所有 tag:

git ls-remote --tags origin

2.3. 删除tag

本地 tag 的删除:

git tag -d <tagName>

远程 tag 的删除:

git push origin :<tagName>

2.4. 标签检出

戳这里

3. blame 追溯文件内容(责备)

戳这里

基础教程 戳这里

通过git blame命令,我们可以查出某个文件的每一行内容到底是由哪位大神所写。

现在就让我们来看看如何使用这个命令。

git blame 文件名 // 查看某个文件内容的修改记录和提交记录
git blame 文件名 | grep "查找词" //模糊查询 此内容的修改者和详细信息
git blame 文件名 -L a,b  // 查询 a行数 到b行数的 修改记录 -L 为行号

六、撤销变更

1 撤销操作

  1. 撤消提交操作
    有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令来重新提交:
 git commit --amend # 弹出以下内容; 
 # 顶部为 commit标题信息; (可以修改)
 # 底部是修改的文件列表
 输入 ESC键 :wq 保存
 把内容追加到commit中,并且commit id 会更新

在这里插入图片描述

  1. 这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令), 那么快照会保持不变,而你所修改的只是提交信息。
    取消暂存的文件

git reset HEAD filename 取消暂存

  1. 撤消对文件的修改

git checkout – filename

你对那个文件在本地的任何修改都会消失,Git 会用最近提交的版本覆盖掉它

2 checkout 检出

讨论的git checkout命令可以使HEAD直接指向一个提交ID,进入头指针分离的状态,从而使工作区回到任意一次提交代码时的样子。git checkout命令也用来创建或切换分支。本篇博客来详细讨论一下git checkout的用法。
介绍以下四种用法:创建、覆盖工作区、头针分离状态、切换分支。

2.1 用法1

git checkout [<commit>] [--] < files>...

如果commit省略,则使用暂存区中的文件来覆盖工作区的指定文件,如果提供了commit,则使用版本库中的某次提交的文件来覆盖暂存区和工作区的指定文件。
示例1:git checkout – a.txt,使用暂存区中的a.txt覆盖工作区中的a.txt,用于丢弃git add命令以后的修改。
示例2:git checkout HEAD – a.txt使用HEAD指向的最新提交来覆盖暂存区和工作区中的a.txt文件。这个命令极其危险,没有撤销的机会。

2.2 用法2

git checkout [branch]

这个用法用来切换分支。示例:git checkout dev,切换到dev分支。切换分支后,HEAD将指向该分支。

注意: 这里checkout 如果是已存在的远程分支 则会默认创建远程分支并且不是基于父分支创建的。形同与clone下来的远程分支

2.3 用法三

git checkout -b <new_branch> <start_commit>

这个用法用来创建分支,注意,这种用法中的-b参数必须指定。<new_branch>是新分支的名字,<start_commit>参数用来指定在哪次提交的基础上来创建新的分支,默认为HEAD指向的最新提交。
示例1:git checkout -b dev,在最新提交上创建一个dev分支。
示例2:git checkout -b dev HEAD^ 在HEAD的上一次提交上创建一个dev分支

2.4 用法4

git checkout <commit>

这个用法是使HEAD直接指向一个提交,并且用该提交的文件树来覆盖暂存区和工作区,然后进入头指针分离状态(detached HEAD)。
场景: 如果你想回到以前的某个提交来查看当时的所有文件,就可以使用这个命令。
最后使用用法2git checkout <branch>来使HEAD指向一个分支,从而结束头指针分离的状态。

场景:当你想基于master中的某个提交创建新的分支。

git checkout <commit> //进入某个提交中
git switch -c <newbranch> //创建新分支

3. 撤销操作

3.1 reset回滚方法

git reset HEAD

撤销git add .的操作 HEAD 后面什么都不带的话 就代表add的所有文件将撤销。 加上文件名就撤销指定文件。

git reset --hard 

回退到 最近的远程仓库的版本

git reset --hard <commitid>

回退到指定commit_id。 推送到远程仓库时,可能会报错 因为提交记录比远程仓库滞后所以需要 git push -f 强制推送。

3.2 revert 反做方法(也实现回滚)

原理: git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。如下图所示:
在这里插入图片描述
适用场景: 如果我们想撤销之前的某一版本,但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。

git revert -n 8b89621019c9adc6fc4d242cd41daeb13aeb9861 
//要反做的commit id

注意:反做只是将commit的操作的文件做了回滚,但是commit记录还在。

3.3 回滚指定文件

3.3.1 场景1:修改了文件/path/to/file,没有提交,但是觉得改的不好,想还原。

解决:

git checkout -- /path/to/file
3.3.2 场景2:修改了文件/path/to/file,已经提交,但是觉得改的不好,想还原到最近版本。

解决:

  1. 首先查看文件的历史版本。git log /path/to/file
  2. 找到你想要还原的版本。如
commit 052c0233bcaef35bbf6e6ebd43bfd6a648e3d93b
Author: panww <panww@gmail.com>
Date: Wed Nov 8 11:48:31 2017 +0800
commit modify/path/to/file
  1. 将文件还原到你想要还原的版本。$ git checkout ${commit} /path/to/file。即$ git checkout 052c0233bcaef35bbf6e6ebd43bfd6a648e3d93b /path/to/file
  2. 这时查看文件,会发现文件已经还原了。(如果没有还原,请刷新再看。)
  3. commit、push。

4 clean 清除

git clean 从你的工作目录中删除所有没有 tracked,没有被管理过的文件。

太可怕,删除了就找不回了,一定要慎用。但是如果被 git add . 就不会被删除。

git clean 和 git reset --hard 的区别

  1. clean 影响没有被 track 过的文件(清除未被 add 或被 commit 的本地修改)
  2. reset 影响被 track 过的文件 (回退到上一个 commit)

所以需要 clean 来删除没有 track 过的文件,reset 删除被 track 过的文件
结合两命令 → 让你的工作目录完全回到一个指定的 的状态

用法详解

参数说明:
n :显示将要被删除的文件
d :删除未被添加到 git 路径中的文件(将 .gitignore 文件标记的文件全部删除)
f : 强制运行
x :删除没有被 track 的文件

git clean -n
// 是一次 clean 的演习, 告诉你哪些文件会被删除,不会真的删除
 
git clean -f
// 删除当前目录下所有没有 track 过的文件
// 不会删除 .gitignore 文件里面指定的文件夹和文件, 不管这些文件有没有被 track 过
 
git clean -f <path>
// 删除指定路径下的没有被 track 过的文件
 
git clean -df
 
// 删除当前目录下没有被 track 过的文件和文件夹
 
git clean -xf
 
// 删除当前目录下所有没有 track 过的文件.
// 不管是否是 .gitignore 文件里面指定的文件夹和文件
 
git clean 
// 对于刚编译过的项目也非常有用
// 如, 他能轻易删除掉编译后生成的 .o 和 .exe 等文件. 这个在打包要发布一个 release 的时候非常有用
 
git reset --hard
git clean -df
git status
// 运行后, 工作目录和缓存区回到最近一次 commit 时候一摸一样的状态。
// 此时建议运行 git status,会告诉你这是一个干净的工作目录, 又是一个新的开始了!

rm 删除

git rm 命令用于删除文件。
如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 Changes not staged for commit 的提示。
git rm 删除文件有以下几种形式:

1、将文件从暂存区和工作区中删除

git rm <file>

如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f。

强行从暂存区和工作区中删除修改后的 runoob.txt 文件:

git rm -f runoob.txt 

如果想把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 --cached 选项即可:

git rm --cached <file>

可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件:

git rm –r * 

重写变更历史

commit --amend

2. rebase 合并记录

场景:单纯这么多次无用的 commit 就很让人不舒服,针对多次无用的commit做了合并。
导致问题:

  1. 不利于代码 review
    设想一下,你要做 code review ,结果一个很小的功能,提交了 60 多次,会不会有一些崩溃?
  2. 会造成分支污染
    你的项目充满了无用的 commit 纪录,如果有一天线上出现了紧急问题,你需要回滚代码,却发现海量的 commit 需要一条条来看。

Rebase 场景一:如何合并多次提交纪录?

1.我们来合并最近的 4 次提交纪录,执行:

git rebase -i HEAD~4

2.这时候,会自动进入 vi 编辑模式:

s cacc52da add: qrcode
s f072ef48 update: indexeddb hack
s 4e84901a feat: add indexedDB floder
s 8f33126c feat: add test2.js

# Rebase 5f2452b2..8f33126c onto 5f2452b2 (4 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

有几个命令需要注意一下:
p,
pick = use commit ;过去式
r,
reword = use commit, but edit the commit message;使用提交,但编辑提交消息
e,
edit = use commit, but stop for amending;使用commit,但停止修改
s,
squash = use commit, but meld into previous commit;使用提交,但融合到之前的提交
f,
fixup = like “squash”, but discard this commit’s log message;像“squash”,但是丢弃这个提交的日志消息
x,
exec = run command (the rest of the line) using shell;使用shell运行命令(行其余部分)
d,
drop = remove commit;删除提交记录

按照如上命令来修改你的提交纪录:

s cacc52da add: qrcode
s f072ef48 update: indexeddb hack
s 4e84901a feat: add indexedDB floder
p 8f33126c feat: add test2.js

3.如果保存的时候,你碰到了这个错误:

error: cannot 'squash' without a previous commit

注意不要合并先前提交的东西,也就是已经提交远程分支的纪录。

  1. 如果你异常退出了 vi 窗口,不要紧张:
git rebase --edit-todo
  1. 这时候会一直处在这个编辑的模式里,我们可以回去继续编辑,修改完保存一下:
git rebase --continue

Rebase 场景二:分支合并

参考:戳这里
1.我们先从 master 分支切出一个 dev 分支,进行开发:

# (master)
git checkout -b feature1

2.这时候,你的同事完成了一次 hotfix,并合并入了 master 分支,此时 master 已经领先于你的 feature1 分支了:
3.恰巧,我们想要同步 master 分支的改动,首先想到了 merge,执行:

# (feature1)
git merge master

图中绿色的点就是我们合并之后的结果; 但是就会在记录里发现一些 merge 的信息,但是我们觉得这样污染了 commit
记录,想要保持一份干净的 commit,怎么办呢?这时候,git rebase 就派上用场了。

  1. git rebase
git checkout feature1 # 切换到需要合并的分支
git rebase origin # 合并分支
  1. 解决冲突
    在rebase的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止rebase并会让你去解决 冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:
git rebase --continue # 这样git会继续应用(apply)余下的补丁。
  1. 在任何时候,你可以用–abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。‘
git rebase --abort

git rebase和git merge的区别

在这里插入图片描述

reflog

git命令log与reflog的比较区别

  1. git log 命令可以显示所有提交过的版本信息
    在这里插入图片描述
    如果感觉太繁琐,可以加上参数 --pretty=oneline,只会显示版本号和提交时的备注信息

在这里插入图片描述
2. git reflog 可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)
例如执行 git reset --hard HEAD~1,退回到上一个版本,用git log则是看不出来被删除的commitid,用git reflog则可以看到被删除的commitid,我们就可以买后悔药,恢复到被删除的那个版本。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NET安梓晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值