Можно ли создать хеш-объект Git вне каталога Git?

Я пытаюсь получить git diff между двумя строками. Работает следующая команда:

git diff $(echo "my first string" | git hash-object -w --stdin) $(echo "my second string" | git hash-object -w --stdin)  --word-diff

Однако он терпит неудачу, если не выполняется внутри каталога Git.

Я считаю, что эта часть команды не работает:

echo "my first string" | git hash-object -w --stdin

Есть ли способ обойти это, чтобы его можно было выполнить вне каталога Git?


person danday74    schedule 04.09.2017    source источник
comment
Кажется, это решает вашу проблему: noredirect=1" title="как мне выполнить команду git, не находясь в папке репозитория"> stackoverflow.com/questions/7149984/   -  person jburtondev    schedule 04.09.2017
comment
спасибо за внимание ... если мой код выполняется на бесчисленном количестве других машин, есть ли способ надежно установить --git-dir ?   -  person danday74    schedule 04.09.2017


Ответы (2)


Я считаю, что эта часть команды не работает:

echo "my first string" | git hash-object -w --stdin

Есть ли способ обойти это, чтобы его можно было выполнить вне каталога git?

Проблема, с которой вы столкнулись, связана с параметром -w, который вы передаете команде git hash-object. Для этой опции требуется существующий репозиторий, поскольку он имеет побочный эффект запись объекта в базу данных git.

Доказательство:

$ echo "my first string" | git hash-object -w --stdin
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

$ echo "my first string" | git hash-object --stdin
3616fdee3ac48e5db02fbf9d5e1c2941cfa3e165

Однако, поскольку вашей конечной целью является получение git diff между двумя заданными строками, у вас должен быть репозиторий git, если вы хотите сделать это с помощью git hash-object1. Для этого вы можете создать временный пустой репозиторий:

$ tmpgitrepo="$(mktemp -d)"

$ git init "$tmpgitrepo"
Initialized empty Git repository in /tmp/tmp.MqBqDI1ytM/.git/

$ (export GIT_DIR="$tmpgitrepo"/.git; git diff $(echo "my first string" | git hash-object -w --stdin) $(echo "my second string" | git hash-object -w --stdin)  --word-diff)
diff --git a/3616fdee3ac48e5db02fbf9d5e1c2941cfa3e165 b/2ab8560d75d92363c8cb128fb70b615129c63371
index 3616fde..2ab8560 100644
--- a/3616fdee3ac48e5db02fbf9d5e1c2941cfa3e165
+++ b/2ab8560d75d92363c8cb128fb70b615129c63371
@@ -1 +1 @@
my [-first-]{+second+} string

$ rm -rf "$tmpgitrepo"

Этот подход можно упаковать в функцию bash:

git-diff-strings()
(
    local tmpgitrepo="$(mktemp -d)"
    trap "rm -rf $tmpgitrepo" EXIT
    git init "$tmpgitrepo" &> /dev/null
    export GIT_DIR="$tmpgitrepo"/.git
    local s1="$1"
    local s2="$2"
    shift 2
    git diff $(git hash-object -w --stdin <<< "$s1") $(git hash-object -w --stdin <<< "$s2") "$@"
)

Использование:

git-diff-strings <string1> <string2> [git-diff-options]

Пример:

git-diff-strings "first string" "second string" --word-diff

1 Обратите внимание, что вы можете git diff две строки создать 2 временных файла, содержащих эти строки, и в этом случае вам не нужен репозиторий git.

person Leon    schedule 04.09.2017
comment
Отличный материал, спасибо, Леон, теперь я добавляю все эти функции в свое приложение - очень признателен: D - person danday74; 05.09.2017

@ danday74 Я не могу написать комментарий на основе вашего отзыва (из-за разрешений на StackOverflow), поэтому вот мой ответ. Вы можете установить переменную среды используя GIT_DIR. Если вы сделаете это на нескольких машинах (вам нужно будет установить эту переменную на таких машинах), то вы сможете надежно установить --git-dir.

Надеюсь это поможет.

person jburtondev    schedule 04.09.2017