1

我在中看到了这样的代码片段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-indexto的值GIT_INDEX_FILE,然后执行 command 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看起来没用..

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

4

3 回答 3

1

您的问题“这是否意味着......”的答案是yes

但是,在解析命令时会发生变量扩展,这样就无法看到设置环境变量然后将其导入 shell 的结果,这就是为什么您没有得到预期结果的原因。

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

$ B=100 env | grep B
B=100

...或者...

$ z=abc sh -c 'echo $z'
abc
于 2012-12-31T05:45:18.460 回答
1

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

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

让我们定义一个变量

$ VAR='value'
$ echo $VAR
value

然后进入新的流程

$ bash

变量未定义

$ echo $VAR

$

但是一旦我们回来

$ exit

var 再次定义

$ echo $VAR
value
$ 

解决这个问题的通常方法是使用导出

$ 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

$ 
于 2012-12-31T05:51:56.460 回答
1

这是否意味着分配TMP-indexto的值GIT_INDEX_FILE,然后执行 command git read-tree HEAD

不完全的。语法:

VAR1=val1 VAR2=val2 somecommand arg1 arg2

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

env VAR1=val1 VAR2=val2 somecommand arg1 arg2

唯一的区别是前一种方法不需要查找和执行/usr/bin/env实用程序(我假设env它不是 shell 内置实用程序),因此它的速度更快。

它也相当于:

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

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

例子

#!/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)"

上面的脚本打印以下输出:

In the shell FOO is value1 (before running python)
In python, FOO is value2
In the shell, FOO is value1 (after running python)

Git 在做什么

在您提供的 Git shell 代码片段中,git stash暂时更改GIT_INDEX_FILE了一些调用,git以便stash可以执行一些索引变异操作而不会弄乱您的索引:

  • 首先,git stash用于git read-tree创建临时索引文件并将其内容初始化为HEAD.
  • 其次,git stash用于git add --interactive询问用户要存储哪些部分并将选择的更改保存在临时索引文件中。
  • 第三,git stash用于git write-tree将临时索引的内容保存为 Git 存储库中的树对象。
  • 第四,git stash比较树对象以HEAD确保您确实选择了要存储的东西。
  • 最后,git stash删除它创建的临时索引文件。
于 2012-12-31T17:32:59.707 回答