弯弯绕绕还是回到的Git

初始设置git 全局变量 (仅第一次使用)

$ git config --global user.name ""
$ git config --global user.email ""

工作区设置

初始化目录

git init

然后在当前目录会出现一个.git的本地仓库

将指定文件添加至暂存区

提交某个文件

git add 文件全称(可以是文件夹,也可以是多个文件,空格隔开)

提交全部 注意空格

git add .

将暂存区内容提交至本地仓库

-m 是添加描述,“ ” 里面的是可以自行修改的

git commit -m “first commit”

git commit -am 对修改的文件可以省略 add直接提交到仓库,但不支持增删文件。

git commit --amend 修正前次提交

添加远程仓库

git remote add origin “远程仓库地址”

将本地仓库push至远程仓库

git push -u origin master

使用-u 后下次可以直接git push 直接master推送到origin

新建文件夹将远程文件拉回

git pull origin master

补充

herry-pick简单用法

将一个分支上的某个commit合并到另一个分支,可用使用cherry-pick命令实现。

比如将dev分支上commit_idf99f2b57b7ee72d55a08e699fbeec34cbac96cb8的提交合并到master分支:
啰嗦一句 git switch -c 是创建并切换分支

1)切换到master分支:

git switch master

2)执行cherry-pick命令:

git cherry-pick f99f2b57b7ee72d55a08e699fbeec34cbac96cb8

3)推送到远程master仓库:

git push

注意master上新的commit id与dev上的id并不相同,即只是将dev上的修改拷贝过来作为一个新的提交,这就会带来一个问题:cherry-pick之后,dev想再次mergemaster,要先对dev分支进行rebase变基。

gitignore

添加.gitignore 可以 忽略某些文件的跟踪

# vscode
.vscode/*
!.vscode/settings.json
.vscode

#keil

!*.OPT
*.UVGUI.*
*.UVGUIX.*
!*.UVMPW
!*.UVPROJ
!*.UVPROJX
!*.UVOPT
!*.UVOPTX
!*.UV2
 
# Source Files
!*.A51
!*.A66
!*.C
!*.CPP
!*.H
!*.INC
!*.S
!*.SRC
 
# Listing Files
*.COD
*.HTM
*.I
*.LST
*.MAP
*.M51
*.M66
*.SCR
 
# Object and HEX Files
# *.
*.elf
*.AXF
*.B[00-31]
*.D
*.CRF
*.ELF
*.HEX
*.H86
*.LIB
*.OBJ
*.O
*.SBR
 
# Build Files
*.BAT
*._IA
*.__I
*._II
*.SCR
 
# Debugger Files
*.INI
 
# Other Files
*.BUILD_LOG.HTM
*.CDB
*.DEP
*.IC
*.LIN
*.LNP
*.ORC
*.PACK
*.PDSC
*.PLG 
*.SCT
*.UVL
*.UVLA
*.UVTSK
*.SFD
*.SFR
*.SVD.XML
*.SVD
*.XML

.gitignore文件修改后,对于修改涉及的文件一般是无法生效的,原因在于已经被追踪的文件记录在.git的缓存中,需要清除缓存。
方法如下:

git rm -r --cached . 
git add . 
git commit -m "*" 
git push

版本回退

丢弃工作区的改动

使用 git add 之前

git checkout -- 文件名

丢弃暂存区的改动

git add 之后 commit 之前

git reset HEAD
 git checkout -- 对应文件名

直接回退到工作区

commit 之后

git reset HEAD <file>... #指的是从库恢复暂存区某一个文件,如果不写 <file>的话,就是把文件恢复到和最新的库一样的状态,fie当然工作区没有变,暂存区变为原来的状态,工作区变还要git checkout --
git reset --hard #指的是恢复某一个库。git reset --hard HEAD^是向前回退版本,其中HEAD后面跟几个^就是往回退几个版本,如果回退100个版本,可以写成 HEAD~100


推荐使用git reset HEAD 然后 git checkout --

谨慎使用git reset --hard 会直接回退工作区

git log  #先查看日志里所有版本的 commit-id(一个哈希值)
git reset --hard + commit-id

也可以使用git reset --hard HEAD^表示1个^表示上一个版本
HEAD~100表示往前100个版本

理解HEAD~

~代表父级,若当前分支有3次提交1->2->3,那么HEAD ~此时就指向第2次提交所对应的commit

理解–soft

若当前分支有3次提交1->2->3,变更内容对应1,2,3,那么 git reset --soft HEAD~ 会将HEAD指针指向2,且索引区和工作去都没有变化,此时索引区为3,工作区为3,只是单纯移动这个指针,若要还原,则需要git commit 就能回到之前1->2->3的状态

理解–mixed(省略默认)

若当前分支有3次提交1->2->3,变更内容对应1,2,3,那么 git reset --soft HEAD~ 会将HEAD指针指向2,且清空索引区,工作区不会变化,此时索引区为空,工作区为3,若要还原,则需要git add . git commit

理解–hard

若当前分支有3次提交1->2->3, 那么 git reset --hard HEAD~ 会将HEAD指针指向2,且清空索引区和工作区,此时索引区为空,工作区为2,丢失所有第三次提交相关信息,又得从第2次提交后的状态开始,若要还原,则需要,在工作区更新为3git add . git commit`

理解git reset HEAD~

等同于git reset --mixed HEAD~

案例演示
进行两次提交

echo “a” >> a.txt git add . git commit -m “change a”
echo “b” >> a.txt git add . git commit -m “change b”

此时的查看commit id 已经有两次提交

commit ed39f0c18e310692307ebf7f38bdd6c73f189e7d
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:06:04 2021 +0800
    change b
commit a60822a64f3fa4041c65b94c8908344a84a35c8a
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:05:41 2021 +0800
    change a

此时进行第三次提交时你不小心使用到了–amend,第二次提交的commit id 就被覆盖了

echo “c” >> c.txt git add . git commit --amend

新的commit

commit 2edae1b7efe0816499523328f66fd68361e920da
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:06:04 2021 +0800
    change b
commit a60822a64f3fa4041c65b94c8908344a84a35c8a
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:05:41 2021 +0800
    change a

此时不要慌,赶紧通过git reflog 查看第二次提交的commit id,可以看到第二次提交的commit ided39f0c

[root@192 git]# git reflog
2edae1b HEAD@{0}: commit (amend): change b
ed39f0c HEAD@{1}: commit: change b
a60822a HEAD@{2}: commit (initial): change a

势必得回滚一下,再想我们是不是应该保留第三次提交在工作区和索引去,因为这是我们今天的工作可丢不得,那么联想上面所讲的,要保留索引区和工作区是不是得使用–soft然后重新提交,那么赶紧安排一下

[root@192 git]# git reset --soft ed39f0c
[root@192 git]# git commit -m "change c"

完成了以上操作再看commit id,是不是就正常了!

[root@192 git]# git log
commit 75d724eb917674c4ad2dd6d4bdb24f1c055bc77d
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:16:05 2021 +0800
    change c
commit ed39f0c18e310692307ebf7f38bdd6c73f189e7d
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:06:04 2021 +0800
    change b
commit a60822a64f3fa4041c65b94c8908344a84a35c8a
Author: root <root@192.168.64.151>
Date:   Fri Dec 24 20:05:41 2021 +0800
    change a

总结

git checkout -- #在git add之前,把工作区的代码用版本库中的代码覆盖掉,注意命令中的–不能
去掉,否则成切换分支的命令了
git reset HEAD #把git add之后,暂存区的内容全部撤销
git reset --hard commitid #把提交到本地仓库中的代码改动进行回退
git reflog #查看HEAD指针的改动日志
git push -f #强制推送本地仓库代码到远程仓库
git diff HEAD #查看工作区file文件和仓库中该文件最新版本的代码有什么区别

单独pull一个文件

git fetch

此操作主要是实现把远程服务器仓库的修改同步至本地仓库

git checkout origin/master -- path/to/file

此操作用于从本地仓库中把指定文件给checkout出来。

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


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

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



git cleangit reset --hard 结合使用。

clean 影响没有被 track 过的文件(清除未被 add 或被 commit 的本地修改)

reset 影响被 track 过的文件 (回退到上一个 commit)

所以需要 clean 来删除没有 track 过的文件,reset删除被 track 过的文件

结合两命令 → 让你的工作目录完全回到一个指定的 <commit> 的状态

参数说明:

  • 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,会告诉你这是一个干净的工作目录, 又是一个新的开始了!

误操作git reset --hard HEAD^

首先首先明白这个命令的含义:

git reset --hard HEAD 是将工作区、暂存取和HEAD保持一致

举例:假设你现在有两个提交 用git log查看

committed_B

committed_A

现在committed_B提交的代码有问题,你现在你要撤销它

你使用了git reset --hard HEAD^

那么现在git log就会变为:

committed_A

同时使用git status没有任何需要git add的文件

因为你代码工作区 暂存区保持一致,因此现在相当于commited_B完全消失了,但是别急,可以找回:

使用git reflog查看过去提交的log

第二使用git cherry-pick取回丢失的提交

具体操作如下:

(1)git reflog

有三个log:

HEAD@{0}:你执行的git reset --hard HEAD^的log

HEAD@{1}:committed_B

HEAD@{2}:commited_A

(2)因为我们想要找回committed_B因此只需要用:

git cherry-pick 836ab53 即可 后面的数字是committed_B的hash值的前七位

至此成功找回丢失的提交

写在后面:

建议使用git reset HEAD^

或者:git reset --soft HEAD^

这样使用,工作区还会保留代码,有修改的余地,除非完全确定,否则不要轻易使用--hard




Last modification:April 16, 2023
如果觉得我的文章对你有用,请帮忙点一下上面的广告