Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'jk/write-broken-index-with-nul-sha1'

Earlier we started rejecting an attempt to add 0{40} object name to
the index and to tree objects, but it sometimes is necessary to
allow so to be able to use tools like filter-branch to correct such
broken tree objects.

* jk/write-broken-index-with-nul-sha1:
  write_index: optionally allow broken null sha1s
  • Loading branch information...
commit 541dc4dfa07f70e66e244be566480ed4699b4fc9 2 parents 9b4aa47 + 83bd743
@gitster gitster authored
View
5 git-filter-branch.sh
@@ -283,11 +283,12 @@ while read commit parents; do
case "$filter_subdir" in
"")
- git read-tree -i -m $commit
+ GIT_ALLOW_NULL_SHA1=1 git read-tree -i -m $commit
;;
*)
# The commit may not have the subdirectory at all
- err=$(git read-tree -i -m $commit:"$filter_subdir" 2>&1) || {
+ err=$(GIT_ALLOW_NULL_SHA1=1 \
+ git read-tree -i -m $commit:"$filter_subdir" 2>&1) || {
if ! git rev-parse -q --verify $commit:"$filter_subdir"
then
rm -f "$GIT_INDEX_FILE"
View
13 read-cache.c
@@ -1818,8 +1818,17 @@ int write_index(struct index_state *istate, int newfd)
continue;
if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
ce_smudge_racily_clean_entry(ce);
- if (is_null_sha1(ce->sha1))
- return error("cache entry has null sha1: %s", ce->name);
+ if (is_null_sha1(ce->sha1)) {
+ static const char msg[] = "cache entry has null sha1: %s";
+ static int allow = -1;
+
+ if (allow < 0)
+ allow = git_env_bool("GIT_ALLOW_NULL_SHA1", 0);
+ if (allow)
+ warning(msg, ce->name);
+ else
+ return error(msg, ce->name);
+ }
if (ce_write_entry(&c, newfd, ce, previous_name) < 0)
return -1;
}
View
49 t/t7009-filter-branch-null-sha1.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='filter-branch removal of trees with null sha1'
+. ./test-lib.sh
+
+test_expect_success 'setup: base commits' '
+ test_commit one &&
+ test_commit two &&
+ test_commit three
+'
+
+test_expect_success 'setup: a commit with a bogus null sha1 in the tree' '
+ {
+ git ls-tree HEAD &&
+ printf "160000 commit $_z40\\tbroken\\n"
+ } >broken-tree
+ echo "add broken entry" >msg &&
+
+ tree=$(git mktree <broken-tree) &&
+ test_tick &&
+ commit=$(git commit-tree $tree -p HEAD <msg) &&
+ git update-ref HEAD "$commit"
+'
+
+# we have to make one more commit on top removing the broken
+# entry, since otherwise our index does not match HEAD (and filter-branch will
+# complain). We could make the index match HEAD, but doing so would involve
+# writing a null sha1 into the index.
+test_expect_success 'setup: bring HEAD and index in sync' '
+ test_tick &&
+ git commit -a -m "back to normal"
+'
+
+test_expect_success 'filter commands are still checked' '
+ test_must_fail git filter-branch \
+ --force --prune-empty \
+ --index-filter "git rm --cached --ignore-unmatch three.t"
+'
+
+test_expect_success 'removing the broken entry works' '
+ echo three >expect &&
+ git filter-branch \
+ --force --prune-empty \
+ --index-filter "git rm --cached --ignore-unmatch broken" &&
+ git log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_done
Please sign in to comment.
Something went wrong with that request. Please try again.