Skip to content

Commit 8098a17

Browse files
Junio C HamanoJunio C Hamano
authored andcommitted
Add git-symbolic-ref
This adds the counterpart of git-update-ref that lets you read and create "symbolic refs". By default it uses a symbolic link to represent ".git/HEAD -> refs/heads/master", but it can be compiled to use the textfile symbolic ref. The places that did 'readlink .git/HEAD' and 'ln -s refs/heads/blah .git/HEAD' have been converted to use new git-symbolic-ref command, so that they can deal with either implementation. Signed-off-by: Junio C Hamano <junio@twinsun.com>
1 parent a876ed8 commit 8098a17

16 files changed

+176
-57
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ git-ssh-push
8282
git-ssh-upload
8383
git-status
8484
git-stripspace
85+
git-symbolic-ref
8586
git-tag
8687
git-tar-tree
8788
git-unpack-file

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ PROGRAMS = \
116116
git-ssh-upload git-tar-tree git-unpack-file \
117117
git-unpack-objects git-update-index git-update-server-info \
118118
git-upload-pack git-verify-pack git-write-tree \
119-
git-update-ref \
119+
git-update-ref git-symbolic-ref \
120120
$(SIMPLE_PROGRAMS)
121121

122122
# Backward compatibility -- to be removed after 1.0

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ extern int get_sha1_hex(const char *hex, unsigned char *sha1);
231231
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
232232
extern int read_ref(const char *filename, unsigned char *sha1);
233233
extern const char *resolve_ref(const char *path, unsigned char *sha1, int);
234+
extern int create_symref(const char *git_HEAD, const char *refs_heads_master);
235+
extern int validate_symref(const char *git_HEAD);
234236

235237
/* General helper functions */
236238
extern void usage(const char *err) NORETURN;

fsck-objects.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -402,25 +402,17 @@ static void fsck_object_dir(const char *path)
402402

403403
static int fsck_head_link(void)
404404
{
405-
int fd, count;
406-
char hex[40];
407405
unsigned char sha1[20];
408-
static char path[PATH_MAX], link[PATH_MAX];
409-
const char *git_dir = get_git_dir();
410-
411-
snprintf(path, sizeof(path), "%s/HEAD", git_dir);
412-
if (readlink(path, link, sizeof(link)) < 0)
413-
return error("HEAD is not a symlink");
414-
if (strncmp("refs/heads/", link, 11))
415-
return error("HEAD points to something strange (%s)", link);
416-
fd = open(path, O_RDONLY);
417-
if (fd < 0)
418-
return error("HEAD: %s", strerror(errno));
419-
count = read(fd, hex, sizeof(hex));
420-
close(fd);
421-
if (count < 0)
422-
return error("HEAD: %s", strerror(errno));
423-
if (count < 40 || get_sha1_hex(hex, sha1))
406+
const char *git_HEAD = strdup(git_path("HEAD"));
407+
const char *git_refs_heads_master = resolve_ref(git_HEAD, sha1, 1);
408+
int pfxlen = strlen(git_HEAD) - 4; /* strip .../.git/ part */
409+
410+
if (!git_refs_heads_master)
411+
return error("HEAD is not a symbolic ref");
412+
if (strncmp(git_refs_heads_master + pfxlen, "refs/heads/", 11))
413+
return error("HEAD points to something strange (%s)",
414+
git_refs_heads_master + pfxlen);
415+
if (!memcmp(null_sha1, sha1, 20))
424416
return error("HEAD: not a valid git pointer");
425417
return 0;
426418
}

git-bisect.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,16 @@ bisect_start() {
3838
# Verify HEAD. If we were bisecting before this, reset to the
3939
# top-of-line master first!
4040
#
41-
head=$(readlink $GIT_DIR/HEAD) || die "Bad HEAD - I need a symlink"
41+
head=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD) ||
42+
die "Bad HEAD - I need a symbolic ref"
4243
case "$head" in
4344
refs/heads/bisect*)
4445
git checkout master || exit
4546
;;
4647
refs/heads/*)
4748
;;
4849
*)
49-
die "Bad HEAD - strange symlink"
50+
die "Bad HEAD - strange symbolic ref"
5051
;;
5152
esac
5253

@@ -135,7 +136,7 @@ bisect_next() {
135136
echo "$rev" > "$GIT_DIR/refs/heads/new-bisect"
136137
git checkout new-bisect || exit
137138
mv "$GIT_DIR/refs/heads/new-bisect" "$GIT_DIR/refs/heads/bisect" &&
138-
ln -sf refs/heads/bisect "$GIT_DIR/HEAD"
139+
GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD refs/heads/bisect
139140
git-show-branch "$rev"
140141
}
141142

git-branch.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ If two arguments, create a new branch <branchname> based off of <start-point>.
1414

1515
delete_branch () {
1616
option="$1" branch_name="$2"
17-
headref=$(readlink "$GIT_DIR/HEAD" | sed -e 's|^refs/heads/||')
17+
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
18+
sed -e 's|^refs/heads/||')
1819
case ",$headref," in
1920
",$branch_name,")
2021
die "Cannot delete the branch you are on." ;;
@@ -67,7 +68,8 @@ done
6768

6869
case "$#" in
6970
0)
70-
headref=$(readlink "$GIT_DIR/HEAD" | sed -e 's|^refs/heads/||')
71+
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
72+
sed -e 's|^refs/heads/||')
7173
git-rev-parse --symbolic --all |
7274
sed -ne 's|^refs/heads/||p' |
7375
sort |

git-checkout.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ if [ "$?" -eq 0 ]; then
7171
echo $new > "$GIT_DIR/refs/heads/$newbranch"
7272
branch="$newbranch"
7373
fi
74-
[ "$branch" ] && ln -sf "refs/heads/$branch" "$GIT_DIR/HEAD"
74+
[ "$branch" ] &&
75+
GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch"
7576
rm -f "$GIT_DIR/MERGE_HEAD"
7677
else
7778
exit 1

git-commit.sh

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,8 @@ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
153153
fi >>.editmsg
154154

155155
PARENTS="-p HEAD"
156-
if [ ! -r "$GIT_DIR/HEAD" ]; then
157-
if [ -z "$(git-ls-files)" ]; then
158-
echo Nothing to commit 1>&2
159-
exit 1
160-
fi
161-
PARENTS=""
162-
current=
163-
else
164-
current=$(git-rev-parse --verify HEAD)
156+
if GIT_DIR="$GIT_DIR" git-rev-parse --verify HEAD >/dev/null 2>&1
157+
then
165158
if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
166159
PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
167160
fi
@@ -194,6 +187,12 @@ else
194187
export GIT_AUTHOR_EMAIL
195188
export GIT_AUTHOR_DATE
196189
fi
190+
else
191+
if [ -z "$(git-ls-files)" ]; then
192+
echo Nothing to commit 1>&2
193+
exit 1
194+
fi
195+
PARENTS=""
197196
fi
198197
git-status >>.editmsg
199198
if [ "$?" != "0" -a ! -f $GIT_DIR/MERGE_HEAD ]

git-sh-setup.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
unset CDPATH
1414

1515
die() {
16-
echo "$@" >&2
16+
echo >&2 "$@"
1717
exit 1
1818
}
1919

20-
[ -h "$GIT_DIR/HEAD" ] &&
20+
case "$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD 2>/dev/null)" in
21+
refs/*) : ;;
22+
*) false ;;
23+
esac &&
2124
[ -d "$GIT_DIR/refs" ] &&
2225
[ -d "$GIT_OBJECT_DIRECTORY/00" ]

git-status.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ report () {
3131
[ "$header" ]
3232
}
3333

34-
branch=`readlink "$GIT_DIR/HEAD"`
34+
branch=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD)
3535
case "$branch" in
3636
refs/heads/master) ;;
3737
*) echo "# On branch $branch" ;;
3838
esac
3939

4040
git-update-index --refresh >/dev/null 2>&1
4141

42-
if test -f "$GIT_DIR/HEAD"
42+
if GIT_DIR="$GIT_DIR" git-rev-parse --verify HEAD >/dev/null 2>&1
4343
then
4444
git-diff-index -M --cached HEAD |
4545
sed 's/^://' |

0 commit comments

Comments
 (0)