From: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
To: Linus Torvalds <torvalds@osdl.org>
Cc: git@vger.kernel.org
Subject: [PATCH 5/5] git-tar-tree: add symlink support
Date: Fri, 6 May 2005 22:56:16 +0200 [thread overview]
Message-ID: <20050506205616.GF19518@lsrfire.ath.cx> (raw)
Add symlink support to git-tar-tree.
---
commit 7cc9bcd638b69e7cb7fed5b9aa8887e71f88c6c7
tree 8326e0ed584a22abfe510f7cf71a5a569157920d
parent 2da87ce547b59294d4d1cf527009395fbec7bf91
author Rene Scharfe <rene.scharfe@lsrfire.ath.cx> 1115312885 +0200
committer Rene Scharfe <rene.scharfe@lsrfire.ath.cx> 1115312885 +0200
Index: tar-tree.c
===================================================================
--- 9eedd772d20dd5a66735f49efe80e17ced40f258/tar-tree.c (mode:100644 sha1:e99adc7dd781cf46efbed82221bf62975a4a3996)
+++ 8326e0ed584a22abfe510f7cf71a5a569157920d/tar-tree.c (mode:100644 sha1:a09cb416595094e493a52dd7f45d943c81c0310a)
@@ -6,10 +6,14 @@
#define TYPEFLAG_AUTO '\0'
#define TYPEFLAG_REG '0'
+#define TYPEFLAG_LNK '2'
#define TYPEFLAG_DIR '5'
#define TYPEFLAG_GLOBAL_HEADER 'g'
#define TYPEFLAG_EXT_HEADER 'x'
+#define EXT_HEADER_PATH 1
+#define EXT_HEADER_LINKPATH 2
+
static const char *tar_tree_usage = "tar-tree <key> [basedir]";
static char block[BLOCKSIZE];
@@ -209,9 +213,13 @@
void *content, unsigned int contentsize)
{
char *p;
- unsigned int pathlen, size;
+ unsigned int pathlen, size, linkpathlen = 0;
size = pathlen = extended_header_len("path", namelen);
+ if (flags & EXT_HEADER_LINKPATH) {
+ linkpathlen = extended_header_len("linkpath", contentsize);
+ size += linkpathlen;
+ }
if (size > RECORDSIZE)
die("tar-tree: extended header too big, wtf?");
write_header(NULL, TYPEFLAG_EXT_HEADER, NULL, NULL, headerfilename,
@@ -221,6 +229,8 @@
append_extended_header_prefix(&p, pathlen, "path");
append_path(&p, is_dir, basepath, prefix, path);
append_char(&p, '\n');
+ if (flags & EXT_HEADER_LINKPATH)
+ append_extended_header(&p, "linkpath", content, contentsize);
write_if_needed();
}
@@ -244,38 +254,60 @@
unsigned int mode, void *buffer, unsigned long size)
{
unsigned int namelen;
- char *p, *header = NULL;
+ char *header = NULL;
unsigned int checksum = 0;
int i;
+ unsigned int ext_header = 0;
if (typeflag == TYPEFLAG_AUTO) {
if (S_ISDIR(mode))
typeflag = TYPEFLAG_DIR;
+ else if (S_ISLNK(mode))
+ typeflag = TYPEFLAG_LNK;
else
typeflag = TYPEFLAG_REG;
}
namelen = path_len(S_ISDIR(mode), basepath, prefix, path);
- if (namelen > 500) {
+ if (namelen > 500)
die("tar-tree: name too log of object %s\n", sha1_to_hex(sha1));
- } else if (namelen > 100) {
- char *sha1_hex = sha1_to_hex(sha1);
+ else if (namelen > 100)
+ ext_header |= EXT_HEADER_PATH;
+ if (typeflag == TYPEFLAG_LNK && size > 100)
+ ext_header |= EXT_HEADER_LINKPATH;
+
+ /* the extended header must be written before the normal one */
+ if (ext_header) {
char headerfilename[51];
- sprintf(headerfilename, "%s.paxheader", sha1_hex);
- /* the extended header must be written before the normal one */
+ sprintf(headerfilename, "%s.paxheader", sha1_to_hex(sha1));
write_extended_header(headerfilename, S_ISDIR(mode),
- 0, basepath, prefix, path,
+ ext_header, basepath, prefix, path,
namelen, buffer, size);
+ }
- header = get_record();
- sprintf(header, "%s.data", sha1_hex);
+ header = get_record();
+
+ if (ext_header) {
+ sprintf(header, "%s.data", sha1_to_hex(sha1));
} else {
- p = header = get_record();
+ char *p = header;
append_path(&p, S_ISDIR(mode), basepath, prefix, path);
}
+ if (typeflag == TYPEFLAG_LNK) {
+ if (ext_header & EXT_HEADER_LINKPATH) {
+ sprintf(&header[157], "see %s.paxheader",
+ sha1_to_hex(sha1));
+ } else {
+ if (buffer)
+ strncpy(&header[157], buffer, size);
+ }
+ }
+
if (S_ISDIR(mode))
mode |= 0755; /* GIT doesn't store permissions of dirs */
+ if (S_ISLNK(mode))
+ mode |= 0777; /* ... nor of symlinks */
sprintf(&header[100], "%07o", mode & 07777);
/* XXX: should we provide more meaningful info here? */
@@ -284,7 +316,9 @@
strncpy(&header[265], "git", 31); /* uname */
strncpy(&header[297], "git", 31); /* gname */
- sprintf(&header[124], "%011lo", S_ISDIR(mode) ? 0 : size);
+ if (S_ISDIR(mode) || S_ISLNK(mode))
+ size = 0;
+ sprintf(&header[124], "%011lo", size);
sprintf(&header[136], "%011lo", archive_time);
header[156] = typeflag;
@@ -331,7 +365,7 @@
if (!strcmp(elttype, "tree")) {
this_prefix.name = path;
traverse_tree(eltbuf, eltsize, &this_prefix);
- } else if (!strcmp(elttype, "blob")) {
+ } else if (!strcmp(elttype, "blob") && !S_ISLNK(mode)) {
write_blocked(eltbuf, eltsize);
}
free(eltbuf);
\f
!-------------------------------------------------------------flip-
reply other threads:[~2005-05-06 20:51 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050506205616.GF19518@lsrfire.ath.cx \
--to=rene.scharfe@lsrfire.ath.cx \
--cc=git@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox