branch: make it operable from a subdirectory.
[git.git] / git-branch.sh
1 #!/bin/sh
2
3 GIT_DIR=`git-rev-parse --git-dir` || exit $?
4
5 usage () {
6     echo >&2 "usage: $(basename $0)"' [-d <branch>] | [[-f] <branch> [start-point]]
7
8 If no arguments, show available branches and mark current branch with a star.
9 If one argument, create a new branch <branchname> based off of current HEAD.
10 If two arguments, create a new branch <branchname> based off of <start-point>.
11 '
12     exit 1
13 }
14
15 headref=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
16
17 delete_branch () {
18     option="$1"
19     shift
20     for branch_name
21     do
22         case ",$headref," in
23         ",$branch_name,")
24             die "Cannot delete the branch you are on." ;;
25         ,,)
26             die "What branch are you on anyway?" ;;
27         esac
28         branch=$(cat "$GIT_DIR/refs/heads/$branch_name") &&
29             branch=$(git-rev-parse --verify "$branch^0") ||
30                 die "Seriously, what branch are you talking about?"
31         case "$option" in
32         -D)
33             ;;
34         *)
35             mbs=$(git-merge-base -a "$branch" HEAD | tr '\012' ' ')
36             case " $mbs " in
37             *' '$branch' '*)
38                 # the merge base of branch and HEAD contains branch --
39                 # which means that the HEAD contains everything in the HEAD.
40                 ;;
41             *)
42                 echo >&2 "The branch '$branch_name' is not a strict subset of your current HEAD.
43     If you are sure you want to delete it, run 'git branch -D $branch_name'."
44                 exit 1
45                 ;;
46             esac
47             ;;
48         esac
49         rm -f "$GIT_DIR/refs/heads/$branch_name"
50         echo "Deleted branch $branch_name."
51     done
52     exit 0
53 }
54
55 force=
56 while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
57 do
58         case "$1" in
59         -d | -D)
60                 delete_branch "$@"
61                 exit
62                 ;;
63         -f)
64                 force="$1"
65                 ;;
66         --)
67                 shift
68                 break
69                 ;;
70         -*)
71                 usage
72                 ;;
73         esac
74         shift
75 done
76
77 case "$#" in
78 0)
79         git-rev-parse --symbolic --all |
80         sed -ne 's|^refs/heads/||p' |
81         sort |
82         while read ref
83         do
84                 if test "$headref" = "$ref"
85                 then
86                         pfx='*'
87                 else
88                         pfx=' '
89                 fi
90                 echo "$pfx $ref"
91         done
92         exit 0 ;;
93 1)
94         head=HEAD ;;
95 2)
96         head="$2^0" ;;
97 esac
98 branchname="$1"
99
100 rev=$(git-rev-parse --verify "$head") || exit
101
102 git-check-ref-format "heads/$branchname" ||
103         die "we do not like '$branchname' as a branch name."
104
105 if [ -e "$GIT_DIR/refs/heads/$branchname" ]
106 then
107         if test '' = "$force"
108         then
109                 die "$branchname already exists."
110         elif test "$branchname" = "$headref"
111         then
112                 die "cannot force-update the current branch."
113         fi
114 fi
115 git update-ref "refs/heads/$branchname" $rev