git-stash中的shell脚本是什么意思,它是如何工作的?

时间:2012-12-31 05:32:54

标签: git bash shell sh git-stash

我在git-stash

中看到了这样的代码段
            rm -f "$TMP-index" &&
            GIT_INDEX_FILE="$TMP-index" git read-tree HEAD &&


            # find out what the user wants
            GIT_INDEX_FILE="$TMP-index" \
                    git add--interactive --patch=stash -- &&

            # state of the working tree
            w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
            die "$(gettext "Cannot save the current worktree state")"

            git diff-tree -p HEAD $w_tree -- >"$TMP-patch" &&
            test -s "$TMP-patch" ||
            die "$(gettext "No changes selected")"

            rm -f "$TMP-index" ||
            die "$(gettext "Cannot remove temporary index (can't happen)")"

我不明白的是这样的表达:

GIT_INDEX_FILE="$TMP-index" git read-tree HEAD

这是否意味着将TMP-index的值分配给GIT_INDEX_FILE,然后执行命令git read-tree HEAD

我不确定。所以我试着写一个类似的命令。

A="1" ls
echo $A

A的值仍为null

我也试过这个:

echo $a
=> 1
k=$(a=100 echo $a)
=> 
echo $k
=> 1

看起来a的值根本没有改变。所以a=100似乎没用..

有没有人对像这样的语法有想法?

3 个答案:

答案 0 :(得分:1)

你问题的答案"这是否意味着......"

但是,在解析命令时会发生变量扩展,现在看到设置环境变量然后将其导入shell的结果为时尚早,这就是为什么你不是这样做的原因。得到你期望的结果。

有多种方法可以查看单行环境变量表达式的结果;你可以观察......

$ B=100 env | grep B
B=100

...或...

$ z=abc sh -c 'echo $z'
abc

答案 1 :(得分:1)

在BASH中,定义变量并在之后运行新流程存在一些问题。

如果您只是定义变量,那么它不会被新进程“继承”

让我们定义一个变量

$ VAR='value'
$ echo $VAR
value

然后进入一个新的过程

$ bash

var未定义

$ echo $VAR

$

但是一旦我们回来了

$ exit

再次定义var

$ echo $VAR
value
$ 

通常的做法是使用export

$ export VAR2='yep'
$ bash
$ echo $VAR2
yep
$ 

您所看到的(似乎是)替代语法,它在子进程中分配变量,但不在原始进程中分配

$ var3='wow' bash  #this line opens a new bash, and assigns the variable for this new bash
$ echo $var3
wow
$ exit
$ echo $var3

$ 

答案 2 :(得分:1)

  

这是否意味着将TMP-index的值分配给GIT_INDEX_FILE,和   然后执行命令git read-tree HEAD

不完全。语法:

VAR1=val1 VAR2=val2 somecommand arg1 arg2

告诉shell执行带有参数somecommandarg1的命令arg2,但somecommand的环境将VAR1设置为{{1} }和val1设置为VAR2。 shell本身不会受这些分配的影响,只会受val2的环境影响。效果相当于:

somecommand

唯一的区别是前一种方法不需要查找和执行env VAR1=val1 VAR2=val2 somecommand arg1 arg2 实用程序(我假设/usr/bin/env不是shell内置实用程序),所以它的速度更快。

它也相当于:

env

注意括号 - 这会导致shell在单独的子shell中执行命令。子shell结束后,对子shell的任何更改(例如变量赋值)都不会保留。

实施例

(export VAR1=val1 VAR2=val2; somecommand arg1 arg2)

以上脚本打印以下输出:

#!/bin/sh
FOO=value1
printf %s\\n "In the shell, FOO is ${FOO} (before running python)"
FOO=value2 python -c 'import os; print "In python, FOO is", os.environ["FOO"]'
printf %s\\n "In the shell, FOO is ${FOO} (after running python)"

Git正在做什么

在您提供的Git shell代码片段中,In the shell FOO is value1 (before running python) In python, FOO is value2 In the shell, FOO is value1 (after running python) 暂时更改了git stash GIT_INDEX_FILE的一些调用,以便git可以执行一些索引变异操作没有弄乱你的索引:

  • 首先,stash使用git stash创建临时索引文件,并将其内容初始化为git read-tree中的任何内容。
  • 其次,HEAD使用git stash向用户询问要隐藏哪些部分并将所选更改保存在临时索引文件中。
  • 第三,git add --interactive使用git stash将临时索引的内容保存为Git存储库中的树对象。
  • 第四,git write-tree将树对象与git stash进行比较,以确保您实际选择了要藏匿的东西。
  • 最后,HEAD删除它创建的临时索引文件。