Loading... 弯弯绕绕还是回到的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_id`为`f99f2b57b7ee72d55a08e699fbeec34cbac96cb8`的提交合并到`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`想再次`merge`到`master`,要先对`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 ``` <div class="tip inlineBlock error"> 推荐使用git reset HEAD 然后 git checkout -- 谨慎使用git reset --hard 会直接回退工作区 </div> ``` 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次提交后的状态开始,若要还原,则需要,在工作区更新为3`git 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 id`是`ed39f0c` ``` [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,没有被管理过的文件。 <div class="tip inlineBlock error"> `git clean` 从你的工作目录中删除所有没有 tracked,没有被管理过的文件。 太可怕,删除了就找不回了,一定要慎用。但是如果被 git add . 就不会被删除。 </div> <div class="tip inlineBlock info"> `git clean` 和 `git reset --hard` 结合使用。 `clean` 影响没有被 track 过的文件(清除未被 `add` 或被 `commit` 的本地修改) `reset` 影响被 `track` 过的文件 (回退到上一个 commit) 所以需要 `clean` 来删除没有 `track` 过的文件,`reset`删除被 `track` 过的文件 结合两命令 → 让你的工作目录完全回到一个指定的 `<commit>` 的状态 </div> ### 参数说明: * 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 <button class="btn m-b-xs btn-success btn-addon" onclick='window.open("https://gitee.com/all-about-git","_blank")'><i class="glyphicon glyphicon-console"></i>扩展链接-Git命令列表</button> <button class="btn m-b-xs btn-success btn-addon" onclick='window.open("http://git.oschina.net/progit/","_blank")'><i class="glyphicon glyphicon-console"></i>Gitee 命令参考</button> <button class="btn m-b-xs btn-success btn-addon" onclick='window.open("https://www.liaoxuefeng.com/wiki/896043488029600","_blank")'><i class="glyphicon glyphicon-console"></i>扩展链接-廖雪峰 Git教程</button> <button class="btn m-b-xs btn-success btn-addon" onclick='window.open("https://blog.csdn.net/m0_56257585/article/details/125334476","_blank")'><i class="glyphicon glyphicon-console"></i>回退参考方法</button> Last modification:April 16, 2023 © Allow specification reprint Support Appreciate the author WeChat Like 0 如果觉得我的文章对你有用,请帮忙点一下上面的广告