summaryrefslogtreecommitdiff
path: root/exporters/darcs/git-darcs
diff options
context:
space:
mode:
Diffstat (limited to 'exporters/darcs/git-darcs')
-rwxr-xr-xexporters/darcs/git-darcs264
1 files changed, 264 insertions, 0 deletions
diff --git a/exporters/darcs/git-darcs b/exporters/darcs/git-darcs
new file mode 100755
index 0000000..eb70338
--- /dev/null
+++ b/exporters/darcs/git-darcs
@@ -0,0 +1,264 @@
+#!/bin/bash
+#
+# git-darcs - bidirectional operation between a darcs repo and git
+#
+# Copyright (c) 2008 by Miklos Vajna <vmiklos@frugalware.org>
+#
+# Based on git-bzr, which is
+#
+# Copyright (c) 2008 Pieter de Bie <pdebie@ai.rug.nl>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+# USA.
+#
+
+add()
+{
+ name="$1"
+ shift
+ location="$1"
+ shift
+ if ! [ -n "$name" -a -n "$location" ]; then
+ echo "Usage: git darcs add name location [darcs-fast-export options]"
+ exit
+ fi
+ if git remote show |grep -q $name; then
+ echo "There is already a remote with that name"
+ exit
+ fi
+ if [ -n "$(git config git-darcs.$name.location)" ]; then
+ echo "There is already a darcs repo with that name"
+ exit
+ fi
+ if [ ! -d $location/_darcs ]; then
+ echo "Remote is not a darcs repository"
+ exit
+ fi
+ git config git-darcs.$name.location $location
+ git config git-darcs.$name.darcs-fast-export-options "$*"
+ echo "Darcs repo $name added. You can fetch it with 'git darcs fetch $name'"
+ if ! [ -z "$*" ]; then
+ echo "darcs-fast-export will get options: $*"
+ fi
+}
+
+get_location()
+{
+ l=$(git config git-darcs.$remote.location)
+ if [ -z "$l" ]; then
+ echo "Cannot find darcs remote with name '$remote'." >&2
+ exit
+ fi
+ echo $l
+}
+
+fetch()
+{
+ remote="$1"
+ shift
+ if ! [ -n "$remote" -a -z "$*" ]; then
+ echo "Usage: git darcs fetch reponame"
+ exit
+ fi
+ location=$(get_location $remote)
+ git_map=$git_dir/darcs-git/$remote-git-map
+ darcs_map=$git_dir/darcs-git/$remote-darcs-map
+ common_opts="--working $git_dir/darcs-git/repo --logfile $git_dir/darcs-git/fetch.log --git-branch=darcs/$remote"
+ dfe_opts=$(git config git-darcs.$remote.darcs-fast-export-options)
+ if [ ! -f $git_map -a ! -f $darcs_map ]; then
+ echo "There doesn't seem to be an existing refmap."
+ echo "Doing an initial import"
+ mkdir -p $git_dir/darcs-git
+ darcs-fast-export --export-marks=$darcs_map $common_opts $dfe_opts $location | \
+ git fast-import --export-marks=$git_map
+ elif [ -f $git_map -a -f $darcs_map ]; then
+ echo "Updating remote $remote"
+ old_rev=$(git rev-parse darcs/$remote)
+ darcs-fast-export --import-marks=$darcs_map --export-marks=$darcs_map $common_opts $dfe_opts $location | \
+ git fast-import --quiet --import-marks=$git_map --export-marks=$git_map
+ new_rev=$(git rev-parse darcs/$remote)
+ if [ "$old_rev" != "$new_rev" ]; then
+ echo "Fetched the following updates:"
+ git shortlog $old_rev..$new_rev
+ else
+ echo "Nothing fetched."
+ exit
+ fi
+ else
+ echo "One of the mapfiles is missing! Something went wrong!"
+ exit
+ fi
+}
+
+pull()
+{
+ remote="$1"
+ shift
+ if ! [ -n "$remote" -a -z "$*" ]; then
+ echo "Usage: git darcs pull reponame"
+ exit
+ fi
+ fetch $remote
+ # see if we need to merge or rebase
+ branch=$(git symbolic-ref HEAD|sed 's|.*/||')
+ if [ "$(git config branch.$branch.rebase)" = "true" ]; then
+ git rebase darcs/$remote
+ else
+ git merge darcs/$remote
+ fi
+}
+
+push()
+{
+ remote="$1"
+ shift
+ if ! [ -n "$remote" -a -z "$*" ]; then
+ echo "Usage: git darcs push reponame"
+ exit
+ fi
+ location=$(get_location $remote)
+ if [ -n "$(git rev-list --left-right HEAD...darcs/$remote | sed -n '/^>/ p')" ]; then
+ echo "HEAD is not a strict child of $remote, cannot push. Merge first"
+ exit
+ fi
+ if [ -z "$(git rev-list --left-right HEAD...darcs/$remote | sed -n '/^</ p')" ]; then
+ echo "Nothing to push. Commit something first"
+ exit
+ fi
+ git_map=$git_dir/darcs-git/$remote-git-map
+ darcs_map=$git_dir/darcs-git/$remote-darcs-map
+ if [ ! -f $git_map -o ! -f $darcs_map ]; then
+ echo "We do not have refmapping yet. Then how can I push?"
+ exit
+ fi
+ echo "Pushing the following updates:"
+ git shortlog darcs/$remote..
+ git fast-export --import-marks=$git_map --export-marks=$git_map HEAD | \
+ (cd $location; darcs-fast-import --import-marks=$darcs_map --export-marks=$darcs_map \
+ --logfile $git_dir/darcs-git/push.log)
+ if [ $? == 0 ]; then
+ git update-ref darcs/$remote HEAD
+ fi
+}
+
+# List the darcs remotes
+list()
+{
+ if [ -z "$*" ]
+ then
+ git config -l | sed -n -e '/git-darcs\..*/ {s/git-darcs\.//; s/\.location=.*//p}'
+ exit
+ elif [ "$#" -eq 1 ]
+ then
+ case $1 in
+ -v|--verbose)
+ git config -l | sed -n -e '/git-darcs\..*/ {s/git-darcs\.//; s/\.location=/\t/p}'
+ exit
+ ;;
+ esac
+ fi
+ echo "Usage: git darcs list [-v|--verbose]"
+ exit 1
+}
+
+# Find the darcs commit(s) supporting a git SHA1 prefix
+find_darcs()
+{
+ sha1="$1"
+ shift
+ if [ -z "$sha1" -o -n "$*" ]
+ then
+ echo "Usage: git darcs find-darcs <sha1-prefix>"
+ exit 1
+ fi
+ for remote in $git_dir/darcs/*
+ do
+ remote=`basename $remote`
+ git_map=$git_dir/darcs-git/$remote-git-map
+ darcs_map=$git_dir/darcs-git/$remote-darcs-map
+ if [ ! -f $git_map -o ! -f $darcs_map ]
+ then
+ echo "Missing mappings for remote $remote"
+ exit 1
+ fi
+ for row in `sed -n -e "/:.* $sha1.*/ s/[^ ]*/&/p" $git_map`
+ do
+ sed -n -e "/$row / {s/[^ ]*//; s/.*/$remote\t&/p}" $darcs_map
+ done
+ done
+}
+
+# Find the git commit(s) supporting a darcs patch prefix
+find_git()
+{
+ patch="$1"
+ shift
+ if [ -z "$patch" -o -n "$*" ]
+ then
+ echo "Usage: git darcs find-git <patch-prefix>"
+ exit 1
+ fi
+ for remote in $git_dir/darcs/*
+ do
+ remote=`basename $remote`
+ git_map=$git_dir/darcs-git/$remote-git-map
+ darcs_map=$git_dir/darcs-git/$remote-darcs-map
+ if [ ! -f $git_map -o ! -f $darcs_map ]
+ then
+ echo "Missing mappings for remote $remote"
+ exit 1
+ fi
+ for row in `sed -n -e "/:.* $patch.*/ s/[^ ]*/&/p" $darcs_map`
+ do
+ sed -n -e "/$row / {s/[^ ]* \(.*\)/$remote\t\1/p}" $git_map
+ done
+ done
+}
+
+git rev-parse 2> /dev/null
+if [ $? != 0 ]; then
+ echo "Must be inside a git repository to work"
+ exit
+fi
+
+git_dir=$(git rev-parse --git-dir)
+# make it absolute
+cd $git_dir
+git_dir=$(pwd)
+cd - >/dev/null
+command="$1"
+shift
+
+case $command in
+ add|push|fetch|pull|list)
+ ;;
+ find-darcs)
+ command=find_darcs
+ ;;
+ find-git)
+ command=find_git
+ ;;
+ *)
+ echo "Usage: git darcs [COMMAND] [OPTIONS]"
+ echo "Commands: add, push, fetch, pull, list, find-darcs, find-git"
+ exit
+ ;;
+esac
+
+
+up=$(git rev-parse --show-cdup)
+[ -z "$up" ] && up="."
+cd $up
+$command "$@"