threads / discuss / 29644

Identify Commit ID from an Extracted Source Snapshot

Subject: Identify Commit ID from an Extracted Source Snapshot

## tl;dr

6 messages between Feb 16, 2012 and Feb 17, 2012.

replies: 5people: 4as markdown or json

James Walmsley· Feb 16, 2012, 22:06 UTC · lore
Hi

I couldn't find this on google, and I have no idea if its even possible. I have several zip files from previous versions of my source code. (I imported svn into git). I would like to add TAGS to git which represent the versions based on the files in my zip archives.

Does anyone know how to do this?
Thanks for any help in advance,
GIT is amazing!
James Walmsley
Michael Schubert· Feb 16, 2012, 23:00 UTC · re: James Walmsley · lore

Re: Identify Commit ID from an Extracted Source Snapshot

On 02/16/2012 11:06 PM, James Walmsley wrote:
Show 7 quoted lines
> I couldn't find this on google, and I have no idea if its even
> possible. I have several zip files from previous versions of my
> source code. (I imported svn into git). I would like to add TAGS to
> git which represent the versions based on the files in my zip
> archives.
> 
> Does anyone know how to do this?

If it's just about providing the ancient code together with the (imported) more recent history from SVN, you could create an extra orphan branch for each zip packet, add the files, commit and eventually tag.

If your question is more like "how do I tell git to find out where this old code fits in my history and eventually place it there", the answer is: you cannot do it. No VCS will do this and especially not Git.

Sam Vilain· Feb 16, 2012, 23:19 UTC · re: Michael Schubert · lore

Re: Identify Commit ID from an Extracted Source Snapshot

On 2/16/12 3:00 PM, Michael Schubert wrote:
Show 18 quoted lines
> On 02/16/2012 11:06 PM, James Walmsley wrote:
>> I couldn't find this on google, and I have no idea if its even
>> possible. I have several zip files from previous versions of my
>> source code. (I imported svn into git). I would like to add TAGS to
>> git which represent the versions based on the files in my zip
>> archives.
>>
>> Does anyone know how to do this?
>
> If it's just about providing the ancient code together with the
> (imported) more recent history from SVN, you could create an extra
> orphan branch for each zip packet, add the files, commit and
> eventually tag.
>
> If your question is more like "how do I tell git to find out where
> this old code fits in my history and eventually place it there",
> the answer is: you cannot do it. No VCS will do this and especially
> not Git.

Once you've got a tree in git which corresponds to the contents of the zip file, you can use git diff --stat TREEID COMMITID

You can get the commitid by obtaining the most recent timestamp for a file within the archive, then just using git rev-list --all --since=... --until=... to get a window of commit IDs, and hunt around until you find the one with the smallest diff.

It's hardly a straightforward thing, usually because the contents of the zip file never quite match the exact contents of source control—think autoconf and other files generated for distribution but not stored in the history. So you need to use a fuzzy search.

Sam
Michael Schubert· Feb 16, 2012, 23:43 UTC · re: Sam Vilain · lore

Re: Identify Commit ID from an Extracted Source Snapshot

On 02/17/2012 12:19 AM, Sam Vilain wrote:
Show 32 quoted lines
> On 2/16/12 3:00 PM, Michael Schubert wrote:
>> On 02/16/2012 11:06 PM, James Walmsley wrote:
>>> I couldn't find this on google, and I have no idea if its even 
>>> possible. I have several zip files from previous versions of my 
>>> source code. (I imported svn into git). I would like to add TAGS
>>> to git which represent the versions based on the files in my zip 
>>> archives.
>>> 
>>> Does anyone know how to do this?
>> 
>> If it's just about providing the ancient code together with the 
>> (imported) more recent history from SVN, you could create an extra 
>> orphan branch for each zip packet, add the files, commit and 
>> eventually tag.
>> 
>> If your question is more like "how do I tell git to find out where 
>> this old code fits in my history and eventually place it there", 
>> the answer is: you cannot do it. No VCS will do this and
>> especially not Git.
> 
> Once you've got a tree in git which corresponds to the contents of
> the zip file, you can use git diff --stat TREEID COMMITID
> 
> You can get the commitid by obtaining the most recent timestamp for a
> file within the archive, then just using git rev-list --all
> --since=... --until=... to get a window of commit IDs, and hunt
> around until you find the one with the smallest diff.
> 
> It's hardly a straightforward thing, usually because the contents of
> the zip file never quite match the exact contents of source
> control—think autoconf and other files generated for distribution but
> not stored in the history.  So you need to use a fuzzy search.

I totally disregared the "slicing and rebuilding history approach", just because I didn't think that's what James is asking about. Could be fun.

Jonathan Nieder· Feb 16, 2012, 23:53 UTC · re: Michael Schubert · lore

Re: Identify Commit ID from an Extracted Source Snapshot

Michael Schubert wrote:
> If your question is more like "how do I tell git to find out where
> this old code fits in my history and eventually place it there",
> the answer is: you cannot do it. No VCS will do this and especially
> not Git.

Wouldn't it be possible to add the tags you want by walking through the commit log to find a matching commit for each tarball?

For example:
	# Usage: "GIT_DIR=<repository> tag-tars <tarballs>"
	# Arguments should be tarballs containing releases in
	# reverse-chronological order.
	# Should be run in an empty directory, which will be
	# used as a workspace.
	# save stdin
	exec 3<&0
	GIT_DIR=$(git rev-parse --resolve-git-dir "$GIT_DIR") || exit 1
	GIT_INDEX_FILE=$GIT_DIR/index.tag-tars
	export GIT_INDEX_FILE
	if test -n "$(git ls-files -c -o | head -1)"
	then
		echo >&2 'fatal: I need an empty directory to work with'
		exit 1
	fi
	for tar
	do
		# empty workspace
		git ls-files | xargs rm -f --
		rm -f "$GIT_INDEX_FILE"
		# get tree name for tarball
		tar --strip-components=1 -xf "$tar"
		git ls-files -o | git update-index --add --stdin
		tree=$(git write-tree)
		# tag the first commit found matching that tree, if any
		git rev-list master |
		while read cmit
		do
			if git diff-tree --quiet $cmit $tree
			then
				git tag -a ${tar%%.*} $cmit <&3
				break
			fi
		done
	done

Variation using --numstat and a path filter to find the closest commit ignoring some files instead of an exact match left as an exercise to the reader.

Hope that helps, Jonathan

Michael Schubert· Feb 17, 2012, 00:14 UTC · re: Jonathan Nieder · lore

Re: Identify Commit ID from an Extracted Source Snapshot

On 02/17/2012 12:53 AM, Jonathan Nieder wrote:
Show 9 quoted lines
> Michael Schubert wrote:
> 
>> If your question is more like "how do I tell git to find out where
>> this old code fits in my history and eventually place it there",
>> the answer is: you cannot do it. No VCS will do this and especially
>> not Git.
> 
> Wouldn't it be possible to add the tags you want by walking through
> the commit log to find a matching commit for each tarball?

I read the question like "How do I insert / prepend my zipped *pre-VCS* version (in)to my Git history in an automated fashion".

Show 47 quoted lines
> For example:
> 
> 	# Usage: "GIT_DIR=<repository> tag-tars <tarballs>"
> 	# Arguments should be tarballs containing releases in
> 	# reverse-chronological order.
> 	# Should be run in an empty directory, which will be
> 	# used as a workspace.
> 
> 	# save stdin
> 	exec 3<&0
> 
> 	GIT_DIR=$(git rev-parse --resolve-git-dir "$GIT_DIR") || exit 1
> 	GIT_INDEX_FILE=$GIT_DIR/index.tag-tars
> 	export GIT_INDEX_FILE
> 
> 	if test -n "$(git ls-files -c -o | head -1)"
> 	then
> 		echo >&2 'fatal: I need an empty directory to work with'
> 		exit 1
> 	fi
> 
> 	for tar
> 	do
> 		# empty workspace
> 		git ls-files | xargs rm -f --
> 		rm -f "$GIT_INDEX_FILE"
> 
> 		# get tree name for tarball
> 		tar --strip-components=1 -xf "$tar"
> 		git ls-files -o | git update-index --add --stdin
> 		tree=$(git write-tree)
> 
> 		# tag the first commit found matching that tree, if any
> 		git rev-list master |
> 		while read cmit
> 		do
> 			if git diff-tree --quiet $cmit $tree
> 			then
> 				git tag -a ${tar%%.*} $cmit <&3
> 				break
> 			fi
> 		done
> 	done
> 
> Variation using --numstat and a path filter to find the closest commit
> ignoring some files instead of an exact match left as an exercise to
> the reader.
Nice, thanks!

← back to recent threads