Last modified 17 months ago Last modified on 12/28/10 23:43:36

Find lost stashs

Finds you commits created by stashes to a certain branch, optionally containing the name of the stash.
Commits found using this method can be reapplied using "git stash apply ${commit}"

Expects the name of the branch and optionally a part of the stash name as argument.

Note: This command is very slow.

find_lost_stash.sh

#!/bin/sh
if [ -z "$1" ] ; then
        echo "Usage: $0 [--unnamed] <branch> [message]"
        exit 1
fi

[ "x$1" == "x--unnamed" ] && unnamed=1 && shift
branch=$1
message=$2

for commit in $(git fsck --full --lost-found | grep commit | awk '{print $3}') ; do
        git show ${commit} | head -n7 | ( [ $unnamed ] && grep "WIP on ${branch}:" || \
                grep "On ${branch}:" ) | grep "${message}" \
                > /dev/null && git show ${commit} | head -n7
done

# Commits found here can be reapplied using "git stash apply ${commit}"

Convert git-diff to svn-diff

A small shellscript to convert a git-diff into an svn-diff compatible form which is understood by TortoiseMerge.

Expects the name of the patch file as argument.

git2svn_diff.sh

#!/bin/sh
if [ -z $1 ] ; then
        echo "Usage: $0 <patch file>"
        exit 1
fi

patch_file=$1

if $(head -n1 "${patch_file}" | grep '^commit' >& /dev/null) ; then
        git_rev=$(head -n1 "${patch_file}" | sed -r -e 's/^commit (.*)/\1/')
        svn_rev=$(git svn find-rev ${git_rev})

        while [ "x${svn_rev}" == "x" ] ; do
                git_rev=$(git rev-parse ${git_rev}^)
                svn_rev=$(git svn find-rev ${git_rev})
        done
else
        git_rev='unknown'
        svn_rev='unknown'
fi


cat ${patch_file} | sed -r -e "
/^diff --git a\/([^[:space:]]*).*/ {
        s/^diff --git a\/([^[:space:]]*).*/Index: \1/
        h
}
/^index.*/ {
        s/^index.*/===================================================================/
}
/^---.*/ {
        g
        s/Index: (.*)/--- \1\t(revision ${svn_rev})/
}
/^\+\+\+.*/ {
        g
        s/Index: (.*)/+++ \1\t(working copy)/
}
/^(new|deleted) file.*/ {
        N
        D
}
" > "${patch_file}".tmp

Clone SVN repository

Cloning from a SVN repository is not trivial, thus here is a quick runthrough that worked for me. Symbolic refs are needed for branches to be clonable, and for them to show up in gitweb.

This method does not help to make the cloned repository work with git-svn on the client side though. That is something I do not yet have a solution for (and neither seems anyone else).

Thanks to doener on #git for helping with this.

clone_svn.sh

#!/bin/sh
if [ -z "$1" -o -z "$2" ] ; then
        echo "Usage: $0 <git repos> <svn repos> [<use svnsync>]"
        echo "Sample: $0 /path/to/git/repos/ svn://host/repos/ yes"
        exit 1
fi

git_repos=$1
svn_repos=$2
svn_sync=${3:+--use-svnsync-props}

echo "Cloning into ${git_repos} from ${svn_repos} ${svn_sync:+using svnsync}"

git --bare --git-dir=${git_repos} init
git --bare --git-dir=${git_repos} svn init --stdlayout ${svn_sync} ${svn_repos}
git --bare --git-dir=${git_repos} svn fetch

git --bare --git-dir=${git_repos} symbolic-ref refs/heads/trunk refs/remotes/trunk
git --bare --git-dir=${git_repos} symbolic-ref refs/heads/master refs/remotes/trunk

for branch in $(git --bare --git-dir=${git_repos} for-each-ref refs/remotes/* | awk '{print $3}') ; do
        git --bare --git-dir=${git_repos} symbolic-ref refs/heads/${branch#refs/remotes/} ${branch}
done
for tag in $(git --bare --git-dir=${git_repos} for-each-ref refs/remotes/tags/* | awk '{print $3}') ; do
        git --bare --git-dir=${git_repos} symbolic-ref refs/tags/${tag#refs/remotes/tags/} ${tag}
done

This does not work: Clone this repos on the clients using:

clone_svnmirror.sh

git clone ${git_repos}
cd ${git_repos_clone}
git svn init --stdlayout --rewrite-root=${svn_repos} ${svn_ssh_repos}

SVN <-> Git gateway

Work in progress! Use at your own risk!

This script is currently being used to keep SVN/the Mainline repository at Gitorious in sync (running on Devurandoms server). It is not an automatic script, any merge conflicts will still have to be resolved.

The latest (development) version can be found at http://gitorious.org/projects/warzone2100/repos/gerard_/blobs/master/tools/gitsvngateway/gitsvngateway

Merging an old patch

This is especially useful if you're trying to apply patches created prior to the c -> cpp rename.

If the patch was created using

git format-patch

then simply use

git am --3way <patch>

If it was created using git diff, then you can trick git am by adding the email style header that it requires:

From: noid <noid@wz2100.net>
Date: 1 Jan 1900
Subject: [PATCH] Old patch

<original diff>

Now you can use:

git am --3way <patch>

Source

Attachments