Skip to content
Snippets Groups Projects
dim 25.4 KiB
Newer Older
Simona Vetter's avatar
Simona Vetter committed
#!/bin/bash

# Copyright © 2012-2015 Intel Corporation
Simona Vetter's avatar
Simona Vetter committed
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
#    Daniel Vetter <daniel.vetter@ffwll.ch>

# drm-intel-next maintainer script

# TODO
# - extract the integration tree logic and make it generally useful, maybe for a
#   drm-integration tree ...
# - Improve nightly-forget to forget a specific merge instead of just the first
#   dinq/dif merge.
Simona Vetter's avatar
Simona Vetter committed
# - add option to check-patch to check stdin
Simona Vetter's avatar
Simona Vetter committed
# - integrate ninja-check? Or too much checkers considered harmful?
#   https://lists.linuxfoundation.org/pipermail/ksummit-discuss/2014-May/000554.html
Simona Vetter's avatar
Simona Vetter committed

# fail on any goof-up
Simona Vetter's avatar
Simona Vetter committed

# User configuration. Set in environment or configuration file. See
# dimrc.sample for an example.
#

# dim configuration file
DIM_CONFIG=${DIM_CONFIG:-$HOME/.dimrc}
if [ -r $DIM_CONFIG ]; then
    . $DIM_CONFIG
fi

# prefix for repo directories
DIM_PREFIX=${DIM_PREFIX:-$HOME/linux}

# main maintainer repo under $DIM_PREFIX
DIM_DRM_INTEL=${DIM_DRM_INTEL:-src}

# name of the $drm_intel_ssh remote within $DIM_DRM_INTEL
DIM_DRM_INTEL_REMOTE=${DIM_DRM_INTEL_REMOTE:-danvet}

# name of the $drm_upstream_git remote within $DIM_DRM_INTEL
DIM_DRM_UPSTREAM_REMOTE=${DIM_DRM_UPSTREAM_REMOTE:-airlied}

# mail user agent. must support a subset of mutt(1) command line options:
# usage: $DIM_MUA [-s subject] [-i file] [-c cc-addr] to-addr [...]
DIM_MUA=${DIM_MUA:-mutt}

# greetings pull request template
DIM_TEMPLATE_HELLO=${DIM_TEMPLATE_HELLO:-$HOME/.dim.template.hello}

# signature pull request template
DIM_TEMPLATE_SIGNATURE=${DIM_TEMPLATE_SIGNATURE:-$HOME/.dim.template.signature}

Simona Vetter's avatar
Simona Vetter committed
today=`date +%Y-%m-%d`

drm_intel_ssh=ssh://git.freedesktop.org/git/drm-intel
drm_intel_git=git://anongit.freedesktop.org/drm-intel
drm_upstream_git=git://people.freedesktop.org/~airlied/linux
Simona Vetter's avatar
Simona Vetter committed
sound_upstream_git=git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
driver_core_upstream_git=git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
linux_upstream_git=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Simona Vetter's avatar
Simona Vetter committed

# email aliases
addr_drm_maintainer="Dave Airlie <airlied@gmail.com>"
addr_intel_gfx_maintainer1="Daniel Vetter <daniel.vetter@ffwll.ch>"
addr_intel_gfx_maintainer2="Jani Nikula <jani.nikula@linux.intel.com>"
addr_intel_gfx="intel-gfx@lists.freedesktop.org"
addr_dri_devel="dri-devel@lists.freedesktop.org"
addr_intel_qa1="\"Sun, Yi\" <yi.sun@intel.com>"
Simona Vetter's avatar
Simona Vetter committed
addr_intel_qa2="\"Christophe Prigent\" <christophe.prigent@intel.com>"
#
# Command line options.
#

DRY_RUN=
Simona Vetter's avatar
Simona Vetter committed
INTERACTIVE=
Simona Vetter's avatar
Simona Vetter committed
function warn_or_fail
{
	if [[ $FORCE ]] ; then
		echo WARNING: $1, but continuing
	else
		echo ERROR: $1, aborting
		exit 1
	fi
}

Simona Vetter's avatar
Simona Vetter committed
while getopts dfi opt; do
	case "$opt" in
		d)
			DRY_RUN=--dry-run
			DRY=echo
			;;
Simona Vetter's avatar
Simona Vetter committed
		i)
			INTERACTIVE='eval read -rsp "Press any key to continue..." -n1 key2; echo'
			;;
Simona Vetter's avatar
Simona Vetter committed
			echo "Try 'dim help' for more information. $opt"
			exit
	esac
done
shift `expr $OPTIND - 1`

# first positional argument is the subcommand
if [ "$#" = "0" ]; then
    subcommand="help"
else
    subcommand="$1"
    shift
fi
if [ "$subcommand" != "setup" -a "$subcommand" != "help" ]; then
	for d in $DIM_PREFIX $DIM_PREFIX/$DIM_DRM_INTEL $DIM_PREFIX/drm-intel-rerere $DIM_PREFIX/drm-intel-nightly; do
		if [ ! -d $d ]; then
			echo "$d is missing, please check your configuration and/or run dim setup"
			exit 1
		fi
	done

	#
	# Internal configuration that depends on a sane setup.
	#
	dim_branches=`(source $DIM_PREFIX/drm-intel-rerere/nightly.conf ; echo $nightly_branches) | \
		xargs -n 1 echo | grep '^origin' | sed -e 's/^origin\///'`
fi
# get message id from file
# $1 = file
message_get_id ()
{
	python <<EOF
from email.parser import Parser
headers = Parser().parse(open('$1', 'r'))
message_id = headers['message-id']
if message_id is not None:
    print(message_id.strip('<>'))
EOF
}

# append a new tag at the end of the commit message of HEAD
# $1 = tag, $2 = value
commit_add_tag ()
	# the first sed deletes all trailing blank lines at the end
	git log -1 --pretty=%B | \
		sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' | \
		sed "\$a$1: $2" | \
		git commit --amend -F-
Simona Vetter's avatar
Simona Vetter committed
function update_linux_next
{
	cd $DIM_PREFIX/drm-intel-nightly

	# always update drm-intel-fixes
	echo -n "Pushing drm-intel-fixes to for-linux-next-fixes... "
	git push $DRY_RUN origin +origin/drm-intel-fixes:for-linux-next-fixes >& /dev/null

	if git merge-base --is-ancestor origin/drm-intel-next-fixes origin/drm-intel-fixes ; then
		# -fixes has caught up to dinf, i.e. we're out of the merge
		# window. Push the next queue.
		echo -n "Out of merge window. Pushing drm-intel-next-queued to for-linux-next... "
		git push $DRY_RUN origin +origin/drm-intel-next-queued:for-linux-next >& /dev/null
Simona Vetter's avatar
Simona Vetter committed
	else
		# dinf is ahead of -fixes, i.e. drm-next has already closed for
		# the next merge window and we've started to gather new fixes
		# for the current -next cycle. Push dinf

		echo -n "Pushing drm-intel-next-fixes to for-linux-next... "
		git push $DRY_RUN origin +origin/drm-intel-next-fixes:for-linux-next >& /dev/null
Simona Vetter's avatar
Simona Vetter committed
	fi
}

function check_conflicts
{
	if git diff | grep '\(<<<<<<<\|=======\|>>>>>>>\||||||||\)' ; then
		if [ -n "$1" ]; then
			echo $*
		fi
Simona Vetter's avatar
Simona Vetter committed
		exit 1
	fi
	true
}

function update_rerere_cache
{
	cd $DIM_PREFIX/drm-intel-rerere/
	cp rr-cache/* $DIM_PREFIX/drm-intel-nightly/.git/rr-cache/ -r
	cd -
}

Simona Vetter's avatar
Simona Vetter committed
function update_nightly
{
	local integration_branch=drm-intel-nightly
	local specfile=`mktemp`
	local time="`date --utc +%Yy-%mm-%dd-%Hh-%Mm-%Ss` UTC"
Simona Vetter's avatar
Simona Vetter committed
	local first=1

	local rerere=$DIM_PREFIX/drm-intel-rerere

	cd $rerere
	if [[ `git status --porcelain | grep -v "^[ ?][ ?]" | wc -l` -gt 0 ]]; then
Simona Vetter's avatar
Simona Vetter committed
		warn_or_fail "-nightly configuration file not commited"
	echo -n "Updating rerere cache and nightly.conf... "
	update_rerere_cache >& /dev/null
	echo "Done."

	source $rerere/nightly.conf
	cd $DIM_PREFIX/$integration_branch
	if ! git branch | grep $integration_branch | grep '\*' >& /dev/null ; then
		echo "Branch setup for the integration repo is borked"
		exit 1
	fi

	for remote in $(echo $nightly_branches | tr " " "\n" | sed 's|/.*$||g' | sort -u); do
		echo -n "Fetching $remote... "
		# git fetch returns 128 if there's nothing to be fetched
		git fetch $remote >& /dev/null || true
		echo "Done."
	done
Simona Vetter's avatar
Simona Vetter committed
	# merge -fixes
	for tree in $nightly_branches; do
		local branch=${tree%:*}
		local sha1=${tree#*:}
Simona Vetter's avatar
Simona Vetter committed
		local name=${branch##*/}

		# the : separator is optional
		if [[ $sha1 == $tree ]] ; then
			sha1=
		fi

		echo -n "Merging $branch... "

		if [[ -n $sha1 ]] ; then
			echo -n "Using override sha1: $sha1... "
Simona Vetter's avatar
Simona Vetter committed
		if [ $first == 1 ] ; then
			echo "Reset. Done."
			git reset --hard $sha1 >& /dev/null
Simona Vetter's avatar
Simona Vetter committed
			first=0
		elif git merge --rerere-autoupdate --ff-only $sha1 >& /dev/null ; then
			# nothing to do if just fast-forward
			echo "Fast-forward. Done."
Simona Vetter's avatar
Simona Vetter committed
		else
Simona Vetter's avatar
Simona Vetter committed
			local fixup_file=$rerere/$integration_branch-$name-fixup.patch

			echo $fixup_file > .fixup_file_path

			git merge --rerere-autoupdate --no-commit $sha1 >& /dev/null || true
Simona Vetter's avatar
Simona Vetter committed
			if [ -f $fixup_file ] ; then
				echo -n "Applying manual fixup patch for $integration_branch merge... "
Simona Vetter's avatar
Simona Vetter committed
				patch -p1 -i $fixup_file
Simona Vetter's avatar
Simona Vetter committed
			fi
			check_conflicts "Fail: conflict merging $tree"
Simona Vetter's avatar
Simona Vetter committed
			git add -u

			# because we filter out fast-forward merges there will
			# always be something to commit
			git commit --no-edit --quiet
			echo "Done."
Simona Vetter's avatar
Simona Vetter committed
		fi

		echo -e "$branch `git rev-parse $sha1`\n\t`git log -1 $sha1 --pretty=format:%s`" >> $specfile
Simona Vetter's avatar
Simona Vetter committed

		$INTERACTIVE
Simona Vetter's avatar
Simona Vetter committed
	done

	echo -n "Adding integration manifest $integration_branch: $time... "
Simona Vetter's avatar
Simona Vetter committed
	mv $specfile integration-manifest
	git add integration-manifest
	git commit --quiet -m "$integration_branch: $time integration manifest"
	echo "Done."
Simona Vetter's avatar
Simona Vetter committed

	echo -n "Pushing $integration_branch... "
	git push $DRY_RUN origin +HEAD >& /dev/null && echo "Done."
Simona Vetter's avatar
Simona Vetter committed

	echo -n "Updating rerere cache... "
Simona Vetter's avatar
Simona Vetter committed
	if git branch | grep rerere-cache | grep '\*' >& /dev/null ; then
		git pull >& /dev/null
		cp $DIM_PREFIX/$integration_branch/.git/rr-cache/* rr-cache -r
Simona Vetter's avatar
Simona Vetter committed
		git add *.patch >& /dev/null || true
		git add rr-cache/* > /dev/null
		if git commit -m "$time: $integration_branch rerere cache update" >& /dev/null; then
			echo -n "New commit. "
Simona Vetter's avatar
Simona Vetter committed
		else
			echo -n "Nothing changed. "
Simona Vetter's avatar
Simona Vetter committed
		fi
		echo -n "Pushing rerere cache... "
		git push $DRY_RUN origin HEAD >& /dev/null && echo "Done."
Simona Vetter's avatar
Simona Vetter committed
	else
		echo "Fail: Branch setup for the rerere-cache is borked."
# push branch $1, rebuild nightly. the rest of the arguments are passed to git
# push.
function dim_push
{
	branch=$1
	shift

	assert_branch $branch

	git push $DRY_RUN $DIM_DRM_INTEL_REMOTE $branch "$@"

	update_nightly
	update_linux_next
}

# ensure we're on branch $1, and apply patches. the rest of the arguments are
# passed to git am.
function dim_apply
{
	local file=`mktemp`

	assert_branch $branch

	if [[ -n `git status --porcelain --untracked-files=no` ]] ; then
		echo Repository not clean, aborting
		exit 2
	fi

Simona Vetter's avatar
Simona Vetter committed
	local message_id=$(message_get_id $file)
	dim_shell_checkpatch "cat $file"

	cat $file | git am -3 "$@"

	if [ -n $message_id ]; then
		commit_add_tag "Link" "http://patchwork.freedesktop.org/patch/msgid/$message_id"
	fi

function magic_patch
{
	if [[ "$1" = "-a" ]]; then
		cd `cat ~/.dim-last-path`
	fi

	local conflict_files=`patch -p1 | grep "saving rejects" | sed -e "s/.*saving rejects to file \(.*\)/\1/"`

	if [[ $conflict_files != "" ]] ; then
		echo conflicts found!
	fi

	for file in $conflict_files ; do
		echo wiggling in ${file%.rej}:
		#cat $file
		rm -f ${file%.rej}.porig
		wiggle -r ${file%.rej} $file || true
	done
}

function dim_cd
	if [[ -d $DIM_PREFIX/$1 ]] ; then
		path=$DIM_PREFIX/$1
		path=$DIM_PREFIX/$DIM_DRM_INTEL

	echo $path > ~/.dim-last-path
	cd $path
function dim_co
{
	dim_cd $1
	if ! git branch | grep $1 > /dev/null ; then
		git checkout -t $DIM_DRM_INTEL_REMOTE/$1
	else
		git checkout $1
	fi
Simona Vetter's avatar
Simona Vetter committed
function check_repo_clean
{
	cd $1
	if ! git diff-index --quiet HEAD ; then
		echo $2 repo not clean, aborting
		exit 1
	fi

}

# $1 is the shell command to display the patch/commit
function dim_shell_checkpatch
{
	local cmd=$1

	$cmd | scripts/checkpatch.pl -q --strict - || true
	if $cmd | grep '^\+.*\WBUG' > /dev/null; then
		warn_or_fail "New BUG macro added"
	fi
	$cmd | grep '^\+.*drm_i915_private_t' > /dev/null && echo "WARNING: New drm_i915_private_t added" || true
}

# $1 is the git sha1 to check
function dim_checkpatch
Simona Vetter's avatar
Simona Vetter committed
{
	local commit=$1

	git --no-pager log --oneline -1 $commit
	dim_shell_checkpatch "git show $commit --pretty=email"
Simona Vetter's avatar
Simona Vetter committed
}

function dim_checkrange
{
	local range

	if [ -z "$1" ]; then
		range="HEAD^..HEAD"
	elif [ -n "`echo $1 | grep '\.\.'`" ]; then
		range="$1"
	else
		range="$1..HEAD"
	fi

	for commit in $(git rev-list --reverse $range); do
		dim_checkpatch $commit || true
	done
}

function prep_pull_mail_greetings
{
	if [ -r $DIM_TEMPLATE_HELLO ]; then
		cat $DIM_TEMPLATE_HELLO
	else
		cat <<-EOF
		Hi Dave,

		EOF
	fi
}

function prep_pull_mail_signature
{
	if [ -r $DIM_TEMPLATE_SIGNATURE ]; then
		cat $DIM_TEMPLATE_SIGNATURE
	else
		cat <<-EOF

		Cheers, Daniel


		EOF
	fi
}

# print pull mail overview based on tags in $@, if any
# without tags, print a reminder
function prep_pull_mail_overview
Simona Vetter's avatar
Simona Vetter committed
{
	if [ "$#" = "0" ]; then
		echo "*** insert pull request overview here ***"
	else
		for tag in $@ ; do
			local obj=`git rev-parse $tag`
			if [[ `git cat-file -t $obj` == "tag" ]] ; then
				echo $tag:
				git cat-file -p $obj | tail -n+6
			fi
		done
	fi
Simona Vetter's avatar
Simona Vetter committed
}

# prepare a pull request mail
# $@: tags, if any, to extract into the pull request overview
Simona Vetter's avatar
Simona Vetter committed
function prep_pull_mail
{
	prep_pull_mail_greetings > ~/tmp/dim-pull-request
	prep_pull_mail_overview $@ >> ~/tmp/dim-pull-request
	prep_pull_mail_signature >> ~/tmp/dim-pull-request
Simona Vetter's avatar
Simona Vetter committed
}

function create_workdir
{
	cd $DIM_PREFIX
	local branches

	if [[ "x$1" = "x" ]]; then
		echo "usage: $0 $subcommand branch|all"
		exit 1
	elif [[ "$1" = "all" ]] ; then
		branches=$dim_branches
	else
		branches=$1
	fi

	for branch in $branches ; do
		if [[ -d $branch ]] ; then
			continue;
		fi

		echo Creating separate workdir for $branch

		$DRY git-new-workdir ${DIM_DRM_INTEL} $branch $branch
# dim_pull_request branch upstream
function dim_pull_request
{
	branch=$1
	upstream=$2
Simona Vetter's avatar
Simona Vetter committed
	if [ "$branch" != "drm-intel-next" ]; then
		assert_branch $branch
	else
		cd $DIM_PREFIX/$DIM_DRM_INTEL
	fi
	git fetch ${upstream%%/*} >& /dev/null || true
	echo "Using $upstream as the upstream"

	if [ "$branch" = "drm-intel-next" ]; then
		# drm-intel-next pulls have been tagged using dim update-next
		drm_intel_next_tags=`git log $DIM_DRM_INTEL_REMOTE/drm-intel-next ^$upstream --decorate | grep "(.*tag: drm-intel-next-" | sed -e "s/^.*(.*tag: \(drm-intel-next-[^ ,]*\).*)$/\1/"`
		prep_pull_mail $drm_intel_next_tags
		tag=`git describe --all --exact $DIM_DRM_INTEL_REMOTE/drm-intel-next`
	else
		tag=$branch-$today
		$DRY git tag -f $tag $DIM_DRM_INTEL_REMOTE/$branch
		$DRY git push -f $DIM_DRM_INTEL_REMOTE $tag
		prep_pull_mail
	fi

	git request-pull $upstream $drm_intel_git $tag >> ~/tmp/dim-pull-request
Simona Vetter's avatar
Simona Vetter committed
	$DRY $DIM_MUA -s "[PULL] $branch" \
		-i ~/tmp/dim-pull-request \
		-c "$addr_intel_gfx" \
		-c "$addr_dri_devel" \
		-c "$addr_intel_gfx_maintainer1" \
		-c "$addr_intel_gfx_maintainer2" \
		"$addr_drm_maintainer"
}

Simona Vetter's avatar
Simona Vetter committed
function setup_dim
{
	if [ ! -d $DIM_PREFIX ]; then
		echo "please set up your repository directory with:"
		echo "    mkdir -p $DIM_PREFIX"
		echo "or update your configuration"
		exit 1
	fi
Simona Vetter's avatar
Simona Vetter committed

	if [ ! -d $DIM_PREFIX/$DIM_DRM_INTEL ]; then
		echo "please set up your maintainer linux repository at $DIM_PREFIX/$DIM_DRM_INTEL with:"
		echo "    cd $DIM_PREFIX"
		echo "    git clone $linux_upstream_git $DIM_DRM_INTEL"
		echo "or update your configuration."
		exit 1
	fi
	cd $DIM_DRM_INTEL
	if ! git remote -v | grep "^origin[[:space:]]" | grep $linux_upstream_git > /dev/null; then
		echo "please set up remote origin for $linux_upstream_git"
		exit 1
	fi
	if ! git remote -v | grep "^$DIM_DRM_INTEL_REMOTE[[:space:]]" | grep $drm_intel_ssh > /dev/null; then
		echo "please set up remote $DIM_DRM_INTEL_REMOTE for $drm_intel_ssh with:"
		echo "    git remote add $DIM_DRM_INTEL_REMOTE $drm_intel_ssh"
		echo "or update your configuration."
		exit 1
	fi
	if ! git remote -v | grep "^$DIM_DRM_UPSTREAM_REMOTE[[:space:]]" | grep $drm_upstream_git > /dev/null; then
		echo "please set up remote $DIM_DRM_UPSTREAM_REMOTE for $drm_upstream_git with:"
		echo "    git remote add $DIM_DRM_UPSTREAM_REMOTE $drm_upstream_git"
		echo "or update your configuration."
	echo "Setting up maintainer-tools ..."
Simona Vetter's avatar
Simona Vetter committed
	if [ ! -d maintainer-tools ]; then
		git clone --reference=$DIM_PREFIX/$DIM_DRM_INTEL/.git $drm_intel_ssh maintainer-tools
Simona Vetter's avatar
Simona Vetter committed
	fi
	cd maintainer-tools
	git config remote.origin.url $drm_intel_ssh
	echo "$DIM_PREFIX/$DIM_DRM_INTEL/.git/objects" > .git/objects/info/alternates
	git repack -a -d -l
Simona Vetter's avatar
Simona Vetter committed
	if ! git branch | grep maintainer-tools > /dev/null ; then
		git checkout -t origin/maintainer-tools
	fi
	cd ..

	echo "Setting up drm-intel-rerere ..."
Simona Vetter's avatar
Simona Vetter committed
	if [ ! -d drm-intel-rerere ]; then
		git clone --reference=$DIM_PREFIX/$DIM_DRM_INTEL/.git $drm_intel_ssh drm-intel-rerere
Simona Vetter's avatar
Simona Vetter committed
	fi
	cd drm-intel-rerere
	git config remote.origin.url $drm_intel_ssh
	echo "$DIM_PREFIX/$DIM_DRM_INTEL/.git/objects" > .git/objects/info/alternates
	git repack -a -d -l
Simona Vetter's avatar
Simona Vetter committed
	if ! git branch | grep rerere-cache > /dev/null ; then
		git checkout -t origin/rerere-cache
	fi
	cd ..

	echo "Setting up drm-intel-nightly ..."
Simona Vetter's avatar
Simona Vetter committed
	if [ ! -d drm-intel-nightly ]; then
		git clone --reference=$DIM_PREFIX/$DIM_DRM_INTEL/.git $drm_intel_ssh drm-intel-nightly
Simona Vetter's avatar
Simona Vetter committed
	fi
	cd drm-intel-nightly
	mkdir -p .git/rr-cache
	git config remote.origin.url $drm_intel_ssh
	echo "$DIM_PREFIX/$DIM_DRM_INTEL/.git/objects" > .git/objects/info/alternates
	git repack -a -d -l
	if ! git branch | grep drm-intel-nightly > /dev/null ; then
		git checkout -t origin/drm-intel-nightly
	fi
Simona Vetter's avatar
Simona Vetter committed
	if git remote | grep drm-upstream > /dev/null ; then
		git config remote.drm-upstream.url $drm_upstream_git
	else
		git remote add drm-upstream $drm_upstream_git
	fi
Simona Vetter's avatar
Simona Vetter committed
	if git remote | grep sound-upstream > /dev/null ; then
		git config remote.sound-upstream.url $sound_upstream_git
	else
		git remote add sound-upstream $sound_upstream_git
	fi
	if git remote | grep driver-core-upstream > /dev/null ; then
		git config remote.driver-core-upstream.url $driver_core_upstream_git
	else
		git remote add driver-core-upstream $driver_core_upstream_git
	fi

	echo "dim setup successfully completed!"
Simona Vetter's avatar
Simona Vetter committed
}

function assert_branch
{
	local branch=$1
	dim_cd $branch
	if git branch | grep $branch | grep '\*' ; then
		return 0
	else
		echo "You're on the wrong branch, expected $branch in $PWD"
		return 1
	fi
case "$subcommand" in
Simona Vetter's avatar
Simona Vetter committed
	setup)
		setup_dim
		;;
	nightly-forget)
		cd $DIM_PREFIX/drm-intel-nightly
Simona Vetter's avatar
Simona Vetter committed
		git fetch origin >& /dev/null
		git reset --hard origin/drm-intel-next-queued >& /dev/null
		git merge origin/drm-intel-fixes
		git rerere forget
		;;
	update-branches|ub)
		cd $DIM_PREFIX/$DIM_DRM_INTEL
		check_repo_clean $DIM_PREFIX/$DIM_DRM_INTEL Kernel

		for branch in $dim_branches ; do
			dim_co $branch
			if git diff --quiet $DIM_DRM_INTEL_REMOTE/$branch; then
				$DRY git rebase
			else
				$DRY git rebase -i
			fi
		dim_co drm-intel-next
Simona Vetter's avatar
Simona Vetter committed
		$DRY git reset --hard $DIM_DRM_INTEL_REMOTE/drm-intel-next
Simona Vetter's avatar
Simona Vetter committed
		# TODO: Restore -nightly merge state from the rerere-cache
		# branch
Simona Vetter's avatar
Simona Vetter committed
		;;
	create-workdir)
		create_workdir $1
		;;
	for-each-workdirs|fw)
		cd $DIM_PREFIX/$DIM_DRM_INTEL
		$@
		for branch in $dim_branches ; do
			if [[ -d $DIM_PREFIX/$branch ]] ; then
				cd $DIM_PREFIX/$branch
				$@
			fi
		done
		;;
Simona Vetter's avatar
Simona Vetter committed
	rebuild-nightly)
		update_nightly
		;;
Simona Vetter's avatar
Simona Vetter committed
	cat-to-fixup)
		cd $DIM_PREFIX/drm-intel-nightly
		cat > `cat .fixup_file_path`
		;;
	push-branch)
		if [[ "x$1" = "x" ]]; then
			echo "usage: $0 $subcommand branch"
			exit 1
		fi
		dim_push "$@"
		;;
Simona Vetter's avatar
Simona Vetter committed
	push-queued|pq)
		dim_push drm-intel-next-queued "$@"
Simona Vetter's avatar
Simona Vetter committed
		;;
	push-next-fixes|pnf)
		dim_push drm-intel-next-fixes "$@"
Simona Vetter's avatar
Simona Vetter committed
	push-fixes|pf)
		dim_push drm-intel-fixes "$@"
Simona Vetter's avatar
Simona Vetter committed
		;;
	checkout|co)
		if [[ "x$1" = "x" ]]; then
			echo "usage: $0 $subcommand branch"
			exit 1
		fi
		dim_co "$@"
		;;
		dim_co drm-intel-next-queued
Simona Vetter's avatar
Simona Vetter committed
		;;
	cof)
		dim_co drm-intel-fixes
Simona Vetter's avatar
Simona Vetter committed
		;;
		dim_co drm-intel-next-fixes
	apply-branch|ab|sob)
Simona Vetter's avatar
Simona Vetter committed
		;;
	apply-queued|aq)
		dim_apply drm-intel-next-queued "$@"
Simona Vetter's avatar
Simona Vetter committed
		;;
	apply-fixes|af)
		dim_apply drm-intel-fixes "$@"
Simona Vetter's avatar
Simona Vetter committed
		;;
	apply-next-fixes|anf)
		dim_apply drm-intel-next-fixes "$@"
Simona Vetter's avatar
Simona Vetter committed
	apply-resolved|ar)
		make -j 20 && git add -u && git am --resolved
		dim_checkpatch HEAD
		git commit --amend &
Simona Vetter's avatar
Simona Vetter committed
		;;
	apply-igt|ai)
		cd ~/xorg/intel-gpu-tools/
		git am --whitespace=fix -3 -s
Simona Vetter's avatar
Simona Vetter committed
		;;
	magic-patch|mp)
		magic_patch "$@"
Simona Vetter's avatar
Simona Vetter committed
		;;
	magic-rebase-resolve|mrr)
		git diff HEAD | patch -p1 -R
		cat .git/rebase-merge/patch | dim mp
		make -j 20
		git add -u
		git rebase --continue
		;;
	tc)
		cd $DIM_PREFIX/$DIM_DRM_INTEL
		tag=$(git tag --contains $1 | grep ^v | sort -V | head -n 1)
		if [[ -n "$tag" ]]; then
			echo "$tag"
		else
			# not in a tagged release, show upstream branches
			git branch -r --contains $1 \
			    $DIM_DRM_INTEL_REMOTE/* \
			    $DIM_DRM_UPSTREAM_REMOTE/drm-next \
			    $DIM_DRM_UPSTREAM_REMOTE/drm-fixes \
			    origin/master | sed 's/^ *//'
		fi
Simona Vetter's avatar
Simona Vetter committed
		;;
	check-patch|cp)
Simona Vetter's avatar
Simona Vetter committed
		;;
	cherry-pick)
		if [[ "x$1" = "x" ]]; then
			echo "usage: $0 $subcommand commit-ish"
			exit 1
		fi
		sha=`git rev-parse $1`
		sha_short=${sha:0:8}

		# need latest -nightly
		git fetch $DIM_DRM_INTEL_REMOTE
		echo Possible fixup patches for your cherry-pick:
		git log --grep=$sha_short --pretty=oneline $sha..$DIM_DRM_INTEL_REMOTE/drm-intel-nightly
		$DRY git cherry-pick $1
		;;
Simona Vetter's avatar
Simona Vetter committed
	pull-request)
		if [[ "x$1" = "x" || "x$2" = "x" ]]; then
			echo "usage: $0 $subcommand branch upstream"
			exit 1
		fi
		dim_pull_request $*
		;;
	pull-request-next)
		upstream=${1:-$DIM_DRM_UPSTREAM_REMOTE/drm-next}
		dim_pull_request drm-intel-next $upstream
Simona Vetter's avatar
Simona Vetter committed
		;;
	pull-request-fixes)
		upstream=${1:-origin/master}
		dim_pull_request drm-intel-fixes $upstream
Simona Vetter's avatar
Simona Vetter committed
		;;
		upstream=${1:-$DIM_DRM_UPSTREAM_REMOTE/drm-next}
		dim_pull_request drm-intel-next-fixes $upstream
		;;
Simona Vetter's avatar
Simona Vetter committed
	update-next)
		assert_branch drm-intel-next-queued
		git fetch $DIM_DRM_INTEL_REMOTE
		if ! git branch --merged $DIM_DRM_INTEL_REMOTE/drm-intel-nightly | grep drm-intel-fixes &> /dev/null ; then
Simona Vetter's avatar
Simona Vetter committed
			echo "drm-intel-fixes not merged into -nigthly, please update!"
			exit 2
		fi
		if ! git branch --merged $DIM_DRM_INTEL_REMOTE/drm-intel-nightly | grep drm-intel-next-queued &> /dev/null ; then
Simona Vetter's avatar
Simona Vetter committed
			echo "drm-intel-next-queued not merged into -nigthly, please update!"
			exit 2
		fi

		driver_date=`date +%Y%m%d`
Simona Vetter's avatar
Simona Vetter committed
		$DRY sed -i -e "s/^#define DRIVER_DATE.*\"[0-9]*\"$/#define DRIVER_DATE\t\t\"$driver_date\"/" \
			drivers/gpu/drm/i915/i915_drv.h
Simona Vetter's avatar
Simona Vetter committed
		$DRY git add drivers/gpu/drm/i915/i915_drv.h
		echo -e "drm/i915: Update DRIVER_DATE to $driver_date\n\nSigned-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>" | \
			git commit -s -F -

		gitk drm-intel-next-queued ^$DIM_DRM_UPSTREAM_REMOTE/drm-next &
Simona Vetter's avatar
Simona Vetter committed

Simona Vetter's avatar
Simona Vetter committed
		git push $DRY_RUN $DIM_DRM_INTEL_REMOTE drm-intel-next-queued:drm-intel-next
Simona Vetter's avatar
Simona Vetter committed
		tag=drm-intel-next-$today
		$DRY git tag -f -a $tag $DIM_DRM_INTEL_REMOTE/drm-intel-next
Simona Vetter's avatar
Simona Vetter committed
		git push $DRY_RUN -f $DIM_DRM_INTEL_REMOTE $tag
Simona Vetter's avatar
Simona Vetter committed

		echo "Updating -testing to latest -nightly"
Simona Vetter's avatar
Simona Vetter committed
		git push $DRY_RUN $DIM_DRM_INTEL_REMOTE +$DIM_DRM_INTEL_REMOTE/drm-intel-nightly:drm-intel-testing
Simona Vetter's avatar
Simona Vetter committed
		$DRY git tag -f drm-intel-testing-$today $DIM_DRM_INTEL_REMOTE/drm-intel-testing
		$DRY git push -f $DIM_DRM_INTEL_REMOTE drm-intel-testing-$today
Simona Vetter's avatar
Simona Vetter committed

		cat > ~/tmp/test-request <<-HERE
		Hi all,

		New -testing cycle with cool stuff:
		HERE
		obj=`git rev-parse $tag`
		if [[ `git cat-file -t $obj` == "tag" ]] ; then
			git cat-file -p $obj | tail -n+6 >> ~/tmp/test-request
		else
			echo "<tag doesn't contain a changelog overview, fix this>" >> ~/tmp/test-request
		fi
		cat >> ~/tmp/test-request <<-HERE

		Happy testing!

		Cheers, Daniel
		HERE

Simona Vetter's avatar
Simona Vetter committed
		$DRY $DIM_MUA -s "Updated drm-intel-testing" \
			-i ~/tmp/test-request \
			-c "$addr_intel_gfx" \
			-c "$addr_intel_gfx_maintainer1" \
			-c "$addr_intel_gfx_maintainer2" \
			"$addr_intel_qa1" \
			"$addr_intel_qa2"
Simona Vetter's avatar
Simona Vetter committed
		;;
Simona Vetter's avatar
Simona Vetter committed
	tag-next)
		cd $DIM_PREFIX/$DIM_DRM_INTEL
		git fetch $DIM_DRM_INTEL_REMOTE

		if [ $(git rev-parse drm-intel-next) == $(git rev-parse drm-intel-next@{u}) ] ; then
			echo "Tagging current drm-intel-next"

			tag=drm-intel-next-$today
			$DRY git tag -f $tag $DIM_DRM_INTEL_REMOTE/drm-intel-next
Simona Vetter's avatar
Simona Vetter committed
			git push $DRY_RUN -f $DIM_DRM_INTEL_REMOTE $tag
Simona Vetter's avatar
Simona Vetter committed
		else
			echo "drm-intel-next not up-to-date, aborting"
			exit
		fi

		;;
	create-branch)
		if [[ "x$1" = "x" ]]; then
			echo "usage: $0 $subcommand branch [commit-ish]"
			exit 1
		fi
		branch=$1
		if [[ "x$2" = "x" ]]; then
			start=HEAD
		else
			start=$2
		fi

		cd $DIM_PREFIX/$DIM_DRM_INTEL

Simona Vetter's avatar
Simona Vetter committed
		$DRY git branch $branch $start
		git push $DRY_RUN $DIM_DRM_INTEL_REMOTE +$branch --set-upstream
		cd $DIM_PREFIX/drm-intel-rerere
Simona Vetter's avatar
Simona Vetter committed
		$DRY echo "nightly_branches=\"\$nightly_branches origin/$branch\"" \
			>> nightly.conf
Simona Vetter's avatar
Simona Vetter committed
		$DRY git add nightly.conf
		$DRY git commit --quiet -m "Adding $branch to -nightly"
		;;
	remove-branch)
		if [[ "x$1" = "x" ]]; then
			echo "usage: $0 $subcommand branch"
			exit 1
		fi
		branch=$1

		cd $DIM_PREFIX/$DIM_DRM_INTEL

Simona Vetter's avatar
Simona Vetter committed
		if ! $DRY git branch -d $branch ; then
			warn_or_fail "Can't remove $branch in working repo"
		fi

		if [[ -d $DIM_PREFIX/$branch ]] ; then
			rm -R $DIM_PREFIX/$branch
		fi

		cd $DIM_PREFIX/drm-intel-nightly
		git push $DRY_RUN origin --delete $branch
Simona Vetter's avatar
Simona Vetter committed
		$DRY git fetch origin --prune
		cd $DIM_PREFIX/drm-intel-rerere
		full_branch="origin/$branch"
Simona Vetter's avatar
Simona Vetter committed
		$DRY sed -e "/${full_branch//\//\\\/}/d" -i nightly.conf
		$DRY git add nightly.conf
		$DRY git commit --quiet -m "Deleted $branch and removed from -nightly"
Simona Vetter's avatar
Simona Vetter committed
	checker)
		rm drivers/gpu/drm/i915/*.o &> /dev/null || true
		rm drivers/gpu/drm/i915/*.ko &> /dev/null || true
		make C=1 drivers/gpu/drm/i915/i915.ko
		;;
	help|*)
		manpage=$DIM_PREFIX/maintainer-tools/dim.rst
		if [ ! -e "$manpage" ]; then
			manpage=$(dirname $(readlink -f $0))/dim.rst
			if [ ! -e "$manpage" ]; then
				echo "Can't find the man page. See http://cgit.freedesktop.org/drm-intel/tree/dim.rst?h=maintainer-tools"
				exit 1
			fi
		fi