Как я могу вручную создать объекты git commit, используя git hash-object? Теперь я работаю с blobs, и в его документации говорится, что он может создавать разные объекты, используя -t, но как вы строите фиксацию с этим?Построение git commit объектов с git hash-object?
ответ
Вот полный и рабочий пример скрипта, который создает commit
объект никогда не работает git commit
:
mkdir project
cd project
git init
hash=`echo -n "" | git hash-object -w --stdin`
tree=`echo -e "100644 blob ${hash}\temptyfile" | git mktree`
commit=`echo -e "yourname\[email protected]\n2013 12:20:15 +0200\ncommittername\[email protected]\n2013 10:13:15 +0200" | git commit-tree ${tree}`
git update-ref refs/heads/master ${commit}
Для проверки того, что сценарий создан коммит, содержащий пустой файл, запустите:
git checkout --
git log --oneline
#2abbdc2 yourname [email protected] 2013 12:20:15 +0200 committername [email protected]
Редактирование: исправлено и улучшено
это «\ tempfile» или «\ temtyfile»? – qbolec
@qbolec '\ t' означает символ' TAB', так что да, это '\ temptyfile'. Однако, если это неверно как '\ tempfile', это означает только, что оно отображается как' empfile' в 'git'-worktree.Таким образом, имя файла, используемого для 'git hash-object', не обязательно должно быть одинаковым для' git mktree'. – Tino
Вы правы. Я исправляю это. –
В интересах читателя:
accepted answer from Arialdo Martini полностью верен и объясняет, как создать пустой репозиторий git
с правильными командами сантехники. Обратите внимание, что его вариант работает и для репозиториев bare
(вы можете создать emptyfile
в git
-dir без каких-либо плохих побочных эффектов).
Этот ответ здесь суммирует его на скрипт с незначительным изменением: содержимое файла берется из «stdin», и файл можно поместить в подкаталог рабочей строки.
Script git-init-with-file-from-stdin.sh new-git-workdir filename 'commit message'
:
#!/bin/bash
mkdir "$1" &&
cd "$1" &&
git init &&
dir="$(dirname "$2")" &&
name="$(basename "${2:-dummyfile}")" &&
obid="$(git hash-object -w --stdin)" &&
treeid="$(git mktree < <(printf '100644 blob %q\t%q\n' "$obid" "$name"))" &&
if [ . = "$dir" ]; then git read-tree -i "$treeid";
else git read-tree --prefix="$dir/" -i "$treeid"; fi &&
git commit -m "${3:-automatic commit}" &&
git reset --hard
Разъяснения для вызова
./git-init-with-file-from-stdin.sh newgitdir path/to/file <<< "hellOw W0rld"
mkdir "$1"
,cd "$1"
,git init
создает новыйgit
worktree и initiailizes его. Он назван в честь первого аргумента (здесьnewgitdir
), который предполагается назвать несуществующим каталогом в существующем пути.dir="$(dirname "$2")"
,name="$(basename "${2:-dummyfile}")"
извлекает путь и часть имени второго аргумента, которая определяет желаемое имя файла. Путь относится к созданномуgit
-workdir. Обратите внимание, что этот аргумент не должен начинаться с/
, иначе команда завершится с ошибкой. Здесьdir=path/to
иname=file
. Если это не указано, новый файл называется «dummyfile» в верхней частиgit
-workdir.obid="$(git hash-object -w --stdin)"
затем сохраняет объект с информацией, считанной изstdin
вgit
репо и сохраняет ША (идентификатор объекта) нового объекта в переменнойobid
. В этом примере содержимоеhellOw W0rld
, а затемNL
.git mktree < <(printf '100644 blob %q\t%q\n' "$obid" "$name")
почти то же самое, что иprintf '100644 blob %q\t%q\n' "$obid" "$name" | git mktree
, и создает правильное дерево git.100644
является обычным файловым режимом. Если вы хотите создать исполняемые файлы, вам нужно100755
.treeid="$(
...)"
затем присваивает это к данному переменномуtreeid
if [ . = "$dir" ]; then git read-tree -i "$treeid";
это читает это вновь созданное дерево в областьgit
ступенчатых для последующего совершения. Однако в этом случае файл должен быть непосредственно в файлеgit
-workdir.else git read-tree --prefix="$dir/" -i "$treeid"; fi
такой же для случая, если вы хотите поместить его в подкаталогgit
-workdir. Самое приятное, чтоgit
автоматически создает для вас все промежуточные узлы каталогов. (К сожалению,--prefix="./"
выдает ошибку.)git commit -m "${3:-automatic commit}"
затем использует хорошо известный обязательство создать коммитgit reset --hard
затем синхронизируетgit
-worktree с последней фиксации.
Изменения для bare
варианта:
Все работает аналогично, за исключением
git commit
(это требует Workdir) иgit reset
(не нужно).заменить
git init &&
с
git init --bare &&
также заменить
git commit -m "${3:-automatic commit}" && git reset --hard
с аналогичной последовательности, как показано в принятом ответе:
commitid="$(git commit-tree "$(git write-tree)" <<< "${3:-automatic commit}")" && git update-ref "refs/heads/master" "$commitid"
Примечания:
Смотрите также https://stackoverflow.com/a/25556917
Это здесь нужно
bash
, а это значит, it works for Windows 10 тоже
- 1. git commit -m vs. git commit -am
- 2. Проблемы с Git Commit
- 3. В чем разница между git commit и git commit-tree
- 4. Поиск SHA1 всех объектов в commit git
- 5. SVN commit vs Git commit
- 6. Есть git add.; git commit - эквивалент git add -A.; git commit -a?
- 7. Удалить Accedental Git Commit
- 8. Разница между git checkout [commit] и git checkout [commit] file
- 9. ^M символов в сообщении git commit (git commit -v)
- 10. Понимание, когда использовать git commit -m и git commit -am
- 11. Потеря моего git commit
- 12. Как отменить git-ветку и git commit
- 13. Commit Ошибка в 'git'
- 14. git workflow after commit
- 15. Git selective commit
- 16. git commit проблемы
- 17. Git User Commit Counts
- 18. delete first git commit
- 19. Git wrong commit parent
- 20. git commit --amend опасен
- 21. Git commit patches
- 22. невидимый git meta commit
- 23. git commit с сообщением шаблона
- 24. Git bundle single commit?
- 25. git revert удалить commit
- 26. SLOC в git commit
- 27. Git override last commit
- 28. Удалить git commit
- 29. Восстановить предыдущий git commit?
- 30. Неожиданный автор Git commit
Вам нужно сделать несколько деревьев объектов в сделать объект фиксации. Вы можете использовать индексный файл и 'write-tree' или просто' mktree'. Вы можете использовать 'хэш-объект', если хотите, но мне кажется, что это очень сложно. –
Знаете ли вы, как использовать хэш-объект для этого? Я знаю о существовании git commit-tree, но можете ли вы сделать это с git-хэш-объектом? – user2291590
Вы просто нанесете на него действительное дерево, как и любой другой объект, например blob. –