git之深入解析如何贮藏工作分支与清理工作目录(代码片段)

Forever_wj Forever_wj     2023-01-04     207

关键词:

一、前言

二、贮藏工作

  • 为了演示贮藏,需要进入项目并改动几个文件,然后可以暂存其中的一个改动。如果运行 git status,可以看到有改动的状态:
$ git status
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb
  • 现在想要切换分支,但是还不想要提交之前的工作,所以贮藏修改。将新的贮藏推送到栈上,运行 git stash 或 git stash push:
$ git stash
Saved working directory and index state \\
  "WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
  • 可以看到工作目录是干净的:
$ git status
# On branch master
nothing to commit, working directory clean
  • 此时,可以切换分支并在其他地方工作,我们的修改被存储在栈上。要查看贮藏的东西,可以使用 git stash list:
$ git stash list
stash@0: WIP on master: 049d078 added the index file
stash@1: WIP on master: c264051 Revert "added file_size"
stash@2: WIP on master: 21d80a5 added number to log
  • 在本例中,有两个之前的贮藏,所以接触到了三个不同的贮藏工作,可以通过原来 stash 命令的帮助提示中的命令将刚刚贮藏的工作重新应用:git stash apply。如果想要应用其中一个更旧的贮藏,可以通过名字指定它,像这样:git stash apply stash@2。 如果不指定一个贮藏,Git 认为指定的是最近的贮藏:
$ git stash apply
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   index.html
	modified:   lib/simplegit.rb

no changes added to commit (use "git add" and/or "git commit -a")
  • 可以看到 Git 重新修改了当我们保存贮藏时撤消的文件。当尝试应用贮藏时有一个干净的工作目录,并且尝试将它应用在保存它时所在的分支,并不是必须要有一个干净的工作目录,或者要应用到同一分支才能成功应用贮藏。可以在一个分支上保存一个贮藏,切换到另一个分支,然后尝试重新应用这些修改。当应用贮藏时工作目录中也可以有修改与未提交的文件,如果有任何东西不能干净地应用,Git 会产生合并冲突。
  • 文件的改动被重新应用了,但是之前暂存的文件却没有重新暂存。想要那样的话,必须使用 --index 选项来运行 git stash apply 命令,来尝试重新应用暂存的修改。如果已经那样做了,那么将回到原来的位置:
$ git stash apply --index
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb
  • 应用选项只会尝试应用贮藏的工作,在堆栈上还有它,可以运行 git stash drop 加上将要移除的贮藏的名字来移除它:
$ git stash list
stash@0: WIP on master: 049d078 added the index file
stash@1: WIP on master: c264051 Revert "added file_size"
stash@2: WIP on master: 21d80a5 added number to log
$ git stash drop stash@0
Dropped stash@0 (364e91f3f268f0900bc3ee613f9f733e82aaed43)
  • 也可以运行 git stash pop 来应用贮藏然后立即从栈上扔掉它。

三、贮藏的创意性使用

  • 有几个贮藏的变种可能也很有用,第一个非常流行的选项是 git stash 命令的 --keep-index 选项,它告诉 Git 不仅要贮藏所有已暂存的内容,同时还要将它们保留在索引中。
$ git status -s
M  index.html
 M lib/simplegit.rb

$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file

$ git status -s
M  index.html
  • 另一个经常使用贮藏来做的事情是像贮藏跟踪文件一样贮藏未跟踪文件。默认情况下,git stash 只会贮藏已修改和暂存的已跟踪文件,如果指定 --include-untracked 或 -u 选项,Git 也会贮藏任何未跟踪文件。然而,在贮藏中包含未跟踪的文件仍然不会包含明确忽略的文件,要额外包含忽略的文件,请使用 --all 或 -a 选项。
$ git status -s
M  index.html
 M lib/simplegit.rb
?? new-file.txt

$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file

$ git status -s
$
  • 最终,如果指定了 --patch 标记,Git 不会贮藏所有修改过的任何东西,但是会交互式地提示哪些改动想要贮藏、哪些改动需要保存在工作目录中。
$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGit
         return `#git_cmd 2>&1`.chomp
       end
     end
+
+    def show(treeish = 'master')
+      command("git show #treeish")
+    end

 end
 test
Stash this hunk [y,n,q,a,d,/,e,?]? y

Saved working directory and index state WIP on master: 1b65b17 added the index file

四、从贮藏创建一个分支

  • 如果贮藏了一些工作,将它留在那儿了一会儿,然后继续在贮藏的分支上工作,在重新应用工作时可能会有问题。如果应用尝试修改刚刚修改的文件,会得到一个合并冲突并不得不解决它。如果想要一个轻松的方式来再次测试贮藏的改动,可以运行 git stash branch 以指定的分支名创建一个新分支,检出贮藏工作时所在的提交,重新在那应用工作,然后在应用成功后丢弃贮藏:
$ git stash branch testchanges
M	index.html
M	lib/simplegit.rb
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

Dropped refs/stash@0 (29d385a81d163dfd45a452a2ce816487a6b8b014)
  • 这是在新分支轻松恢复贮藏工作并继续工作的一个很不错的途径。

五、清理工作目录

  • 对于工作目录中一些工作或文件,想做的也许不是贮藏而是移除,git clean 命令就是用来干这个的。清理工作目录有一些常见的原因,比如说为了移除由合并或外部工具生成的东西,或是为了运行一个干净的构建而移除之前构建的残留。
  • 但是,需要谨慎地使用这个命令,因为它被设计为从工作目录中移除未被追踪的文件。如果改变主意,可能也不一定能找回来那些文件的内容,一个更安全的选项是运行 git stash --all 来移除每一样东西并存放在栈中。
  • 可以使用 git clean 命令去除冗余文件或者清理工作目录,使用 git clean -f -d 命令来移除工作目录中所有未追踪的文件以及空的子目录,-f 意味着“强制(force)”或“确定要移除”,使用它需要 Git 配置变量 clean.requireForce 没有显式设置为 false。
  • 如果只是想要看看它会做什么,可以使用 --dry-run 或 -n 选项来运行命令,这意味着“做一次演习然后告诉你将要移除什么”:
$ git clean -d -n
Would remove test.o
Would remove tmp/
  • 默认情况下,git clean 命令只会移除没有忽略的未跟踪文件,任何与 .gitignore 或其他忽略文件中的模式匹配的文件都不会被移除。如果也想要移除那些文件,例如为了做一次完全干净的构建而移除所有由构建生成的 .o 文件,可以给 clean 命令增加一个 -x 选项。
$ git status -s
 M lib/simplegit.rb
?? build.TMP
?? tmp/

$ git clean -n -d
Would remove build.TMP
Would remove tmp/

$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/
  • 如果不知道 git clean 命令将会做什么,在将 -n 改为 -f 来真正做之前总是先用 -n 来运行它做双重检查。另一个小心处理过程的方式是使用 -i 或 “interactive” 标记来运行它,将会以交互模式运行 clean 命令,这种方式下可以分别地检查每一个文件或者交互地指定删除的模式。
$ git clean -x -i
Would remove the following items:
  build.TMP  test.o
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each             5: quit
    6: help
What now>
  • 在一种奇怪的情况下,可能需要格外用力才能让 Git 清理工作目录。如果恰好在工作目录中复制或克隆了其他 Git 仓库(可能是子模块),那么即便是 git clean -fd 都会拒绝删除这些目录。这种情况下,需要加上第二个 -f 选项来强调。

git之深入解析如何使用git的分布式工作流程与如何管理多人开发贡献的项目(代码片段)

...以及托管服务器的相关技术,请参考博客:Git之深入解析Git的安装流程与初次 查看详情

git之深入解析如何在应用中嵌入git(代码片段)

...式工作流程等相关的技术和能力,请参考:Git之深入解析Git的安装流程与初次运行Git前的环境 查看详情

git之深入解析如何通过gpg签署和验证工作(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析如何借助git的配置方法和钩子机制来自定义git需求(代码片段)

...式工作流程等相关的技术和能力,请参考:Git之深入解析Git的安装流程与初次运行Git前的环境 查看详情

git之深入解析如何重写提交历史(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Gi 查看详情

git之深入解析如何选择修订的版本(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析如何交互式暂存(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析reset命令原理以及与checkout命令的区别(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析如何替换数据库中的git对象(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析如何运行自己的git仓库托管服务器(代码片段)

一、协议了解了Git的基础使用流程和Git的分支管理之后,我们应该已经有办法使用Git来完成日常的工作。然而,为了使用Git协作功能,还需要有远程的Git仓库。尽管在技术上可以从个人仓库进行推送(push)和... 查看详情

git之深入解析如何使用git调试项目源码中的问题(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

github之深入解析脚本·自定义与修改github来更好地为特定的工作流程工作(代码片段)

一、服务与钩子GitHub仓库管理中的钩子与服务区块是GitHub与外部系统交互最简单的方式。①服务首先来看一下服务,钩子与服务整合都可以在仓库的设置区块中找到,就在我们之前添加协作者与改变项目的默认分支的地... 查看详情

vscode用git拉取代码,提示:在签出前,请清理存储库工作树。请问是啥问题,如何解决。

参考技术A1、gitclone https://github.com/?/PrettyGirls.git 2、查看本地分支和远程分支,cdPrettyGirls到工程目录下;gitbranch-al查看本地和远程的所有分支。 这里成功看到了所有的分支:其中master是本地分支,前面的星号*表示正... 查看详情

git之深入解析高级合并(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析凭证存储(代码片段)

...暂存区和轻量级地分支及合并的威力。如果想进一步对Git深入学习,可以学习一些Git更加强大的功能,这些功能可能并不会在日常操作中使用,但在某些时候可能还是会起到一定的关键性作用。如果还不清楚Git的基础... 查看详情

git之深入解析常用命令速查大全与reset模式分析(代码片段)

一、Git工作流程四个区:Workspace:工作区Index/Stage:暂存区(和gitstash命令暂存的地方不一样)Repository:仓库区(或本地仓库)Remote:远程仓库五种状态:未修改Origin已修改Modified已暂存Staged... 查看详情

产品管理开发之git工作流和分支规范推荐

...大大提高了开发效率和产品的交付频率。本篇,针对Git的工作流和分支使用,进行了一些推荐。 目录1    产品管理开发之Git工作流和分支规范推荐1.1     Git工作流模型推荐1.2  & 查看详情

ios之深入解析cocoapods的工作原理与源码分析

一、Cocoapods简介①Cocoapods是什么?Cocoapods是一个运行在Ruby环境下,负责管理iOS项目中第三方开源库的工具,它可以解决库与库之间的依赖关系,同时通过创建一个Xcode的workspace来将这些第三方库与工程连接起来,方便开发使用。... 查看详情