File tree 2 files changed +31
-1
lines changed
2 files changed +31
-1
lines changed Original file line number Diff line number Diff line change @@ -977,8 +977,24 @@ struct GitFileSystemObjectSinkImpl : GitFileSystemObjectSink
977
977
978
978
void pushBuilder (std::string name)
979
979
{
980
+ const git_tree_entry * entry;
981
+ Tree prevTree = nullptr ;
982
+
983
+ if (!pendingDirs.empty () &&
984
+ (entry = git_treebuilder_get (pendingDirs.back ().builder .get (), name.c_str ())))
985
+ {
986
+ /* Clone a tree that we've already finished. This happens
987
+ if a tarball has directory entries that are not
988
+ contiguous. */
989
+ if (git_tree_entry_type (entry) != GIT_OBJECT_TREE)
990
+ throw Error (" parent of '%s' is not a directory" , name);
991
+
992
+ if (git_tree_entry_to_object ((git_object * *) (git_tree * *) Setter (prevTree), *repo, entry))
993
+ throw Error (" looking up parent of '%s': %s" , name, git_error_last ()->message );
994
+ }
995
+
980
996
git_treebuilder * b;
981
- if (git_treebuilder_new (&b, *repo, nullptr ))
997
+ if (git_treebuilder_new (&b, *repo, prevTree. get () ))
982
998
throw Error (" creating a tree builder: %s" , git_error_last ()->message );
983
999
pendingDirs.push_back ({ .name = std::move (name), .builder = TreeBuilder (b) });
984
1000
};
Original file line number Diff line number Diff line change @@ -97,3 +97,17 @@ chmod +x "$TEST_ROOT/tar_root/foo"
97
97
tar cvf " $TEST_ROOT /tar.tar" -C " $TEST_ROOT /tar_root" .
98
98
path=" $( nix flake prefetch --refresh --json " tarball+file://$TEST_ROOT /tar.tar" | jq -r .storePath) "
99
99
[[ $( cat " $path /foo" ) = bar ]]
100
+
101
+ # Test a tarball with non-contiguous directory entries.
102
+ rm -rf " $TEST_ROOT /tar_root"
103
+ mkdir -p " $TEST_ROOT /tar_root/a/b"
104
+ echo foo > " $TEST_ROOT /tar_root/a/b/foo"
105
+ echo bla > " $TEST_ROOT /tar_root/bla"
106
+ tar cvf " $TEST_ROOT /tar.tar" -C " $TEST_ROOT /tar_root" .
107
+ echo abc > " $TEST_ROOT /tar_root/bla"
108
+ echo xyzzy > " $TEST_ROOT /tar_root/a/b/xyzzy"
109
+ tar rvf " $TEST_ROOT /tar.tar" -C " $TEST_ROOT /tar_root" ./a/b/xyzzy ./bla
110
+ path=" $( nix flake prefetch --refresh --json " tarball+file://$TEST_ROOT /tar.tar" | jq -r .storePath) "
111
+ [[ $( cat " $path /a/b/xyzzy" ) = xyzzy ]]
112
+ [[ $( cat " $path /a/b/foo" ) = foo ]]
113
+ [[ $( cat " $path /bla" ) = abc ]]
You can’t perform that action at this time.
0 commit comments