Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Import foreign commit prefixed instead of transplanting the tree #10

Closed
wants to merge 1 commit into from

2 participants

@kentfredric
Collaborator

verbatim

This will help avoid problems with rebase.

NOTE: the .gitrepo file is still added at the merge stage, and that
file will be lost in subsequent rebases/merges.

Also, the equivalent code for pull is not in place yet.

It relies on knowledge of the internal format specification for the raw
tree blob object ( what you get if you do git cat-file tree <TREESHA> )
and writes one by hand with a bit of ninja tricks from perl's pack
function.

This is because silly git, unlike everywhere else in git, stores SHA1s
in TREE blobs in binary encoding instead of in Hex. :(

Tree Blob format is

  TYPE SPACE FILENAME NULL BINARYSHA1

Where TYPE is 040000 for directories/trees.

Signed-off-by: Kent Fredric kentfredric@gmail.com

@kentfredric kentfredric Import foreign commit prefixed instead of transplanting the tree
verbatim

This will help avoid problems with rebase.

NOTE: the '.gitrepo' file is still added at the merge stage, and _that_
file will be lost in subsequent rebases/merges.

Also, the equivalent code for 'pull' is not in place yet.

It relies on knowledge of the internal format specification for the raw
tree blob object ( what you get if you do `git cat-file tree <TREESHA>` )
and writes one by hand with a bit of ninja tricks from `perl`'s `pack`
function.

This is because silly git, unlike everywhere else in git, stores SHA1s
in TREE blobs in *binary encoding* instead of in Hex. :(

Tree Blob format is

  TYPE SPACE FILENAME NULL BINARYSHA1

Where `TYPE` is 040000 for directories/trees.

Signed-off-by: Kent Fredric <kentfredric@gmail.com>
5f165f8
@kentfredric
Collaborator

I'm not entirely sure you'd want to stuff the .gitrepo file in the parent2 commit either, its doable, but a little bit of legwork, and it would require more code to remove.

Oh, and "Former" would be impossible if it was in that commit, because it would have to refer to itself.

@ingydotnet
Owner

I rewrote the clone command to fetch the remote, checkout the content into the subdir as a WORK TREE, add the .gitrepo file and then do it all as one commit. I changed former to parent, as it now points to the mainline HEAD commit before the clone.

I also made the commit message look better (I hope) so the history is hopefully very nice.

@ingydotnet ingydotnet closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 1, 2014
  1. @kentfredric

    Import foreign commit prefixed instead of transplanting the tree

    kentfredric authored
    verbatim
    
    This will help avoid problems with rebase.
    
    NOTE: the '.gitrepo' file is still added at the merge stage, and _that_
    file will be lost in subsequent rebases/merges.
    
    Also, the equivalent code for 'pull' is not in place yet.
    
    It relies on knowledge of the internal format specification for the raw
    tree blob object ( what you get if you do `git cat-file tree <TREESHA>` )
    and writes one by hand with a bit of ninja tricks from `perl`'s `pack`
    function.
    
    This is because silly git, unlike everywhere else in git, stores SHA1s
    in TREE blobs in *binary encoding* instead of in Hex. :(
    
    Tree Blob format is
    
      TYPE SPACE FILENAME NULL BINARYSHA1
    
    Where `TYPE` is 040000 for directories/trees.
    
    Signed-off-by: Kent Fredric <kentfredric@gmail.com>
This page is out of date. Refresh to see the latest.
Showing with 12 additions and 2 deletions.
  1. +12 −2 lib/git-subrepo
View
14 lib/git-subrepo
@@ -115,11 +115,21 @@ command:clone() {
# Create a tree object from the index:
local tree_commit="$(git write-tree)"
+ local parent2_orig_tree="$(git log --max-count=1 --format=%T $upstream_head)"
+
+ # Make a tree object with one dir "subdir" which points to parent2_orig_tree
+ # WARNING: Arbitrary code execution risk here.
+ local parent2_tree="$(
+ (
+ echo -n "040000 ${subdir}";
+ perl -e "print chr(0) . pack q[H*], q[$parent2_orig_tree];";
+ ) | git hash-object -w -t tree --stdin
+ )";
+
# Create a commit object from the tree:
update_commit="$(
action-message |
- git commit-tree \
- "$(git log --max-count=1 --format=%T "$upstream_head")"
+ git commit-tree "$parent2_tree"
)"
# Create a merge commit:
Something went wrong with that request. Please try again.