* '.git file' alternative, native (cross-platform) workdir support.
@ 2008-02-29 12:27 Marius Storm-Olsen
2008-02-29 12:54 ` Johannes Schindelin
0 siblings, 1 reply; 8+ messages in thread
From: Marius Storm-Olsen @ 2008-02-29 12:27 UTC (permalink / raw)
To: Git Mailing List, msysGit
[-- Attachment #1.1: Type: text/plain, Size: 2438 bytes --]
Hi guys,
I just caught a glimpse of the '.git file' efforts, as a file for
redirection to a real repository.
As far as I can tell, the reason for adding the support is to in the
end provide a cross-platform way of supporting workdirs. (If this is
not the [main] point, please point me to the thread describing the
real reason, I couldn't find it.)
However, wouldn't simply redirecting everything into a real repo then
create problems with shared index file and more? A problem which could
be tacled by file suffixes or other methods, I'm sure, but which would
require even more patches to achieve the goal.
I was actually thinking about the whole workdir thing the other day,
since I mainly work on Windows, and constantly green of envy of the
'mainly Linux' guys. I figured, why not just add support for file
redirection in
char *git_path(const char *fmt, ...)
which we use all over the place? That surely is easy and
cross-platform :-)
Attached you'll find a patch which will achieve 'native workdir'
support on all platforms, independent of underlying file system. And
if you ignore the code added to builtin-init-db.c &
builtin-rev-parse.c for minimal usage support, it's a mere 104 lines
touched. The patch should apply cleanly on both git's next branch, and
Hannes' j6t master branch (the mingw port).
Please note that the patch is not meant for end-user consumption, nor
does it follow Git coding standards. It's just meant as a proof of
concept, and as a means of discussion.
Also note that this way of supporting workdirs suffers from the same
'flaws' the current git-new-workdir has (locking of repo etc).
If people want, I can work with it, and implement this properly (with
its own builtin-workdir, test cases etc). As I see it, the '.git file'
concept still has some way to go. Maybe the '.git file' concept is the
best way in the end, but that this way is an 'ok' temporary way of
doing it?
^shrug^ - Input please!
To try out the patch, apply it on git 'next' branch, then in some
random directory:
git init --workdir-for=<abs-path to repo>
git reset --hard
.. hack away as normal ..
(I know I know, it just a quick hack to let ppl play with it.)
PS. Sorry for the patch being an attachment, I'm a Thunderbird slave.
(Someone really needs to make a Thunderbird addon for sending Git
patches ;-)
--
.marius
[-- Attachment #1.2: 0001-Add-cross-platform-workdir-support.patch --]
[-- Type: text/plain, Size: 10450 bytes --]
From a38bf926edcba780445ae2a67eb8fe33b266a94f Mon Sep 17 00:00:00 2001
From: Marius Storm-Olsen <marius@trolltech.com>
Date: Thu, 28 Feb 2008 13:22:42 +0100
Subject: [PATCH] Add cross-platform workdir support
---
builtin-init-db.c | 53 ++++++++++++++++++++++++++++++++++++++-----
builtin-rev-parse.c | 19 +++++++++++++++
cache.h | 2 +
environment.c | 63 +++++++++++++++++++++++++++++++++++++++++++++-----
path.c | 37 +++++++++++++++++++++++++++--
setup.c | 2 +-
6 files changed, 159 insertions(+), 17 deletions(-)
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 79eaf8d..94622f9 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -310,7 +310,7 @@ static void guess_repository_type(const char *git_dir)
}
static const char init_db_usage[] =
-"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
+"git-init [-q | --quiet] [--template=<template-directory>] [--shared] [--workdir-for=<repository>]";
/*
* If you want to, you can share the DB area with any number of branches.
@@ -323,8 +323,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
const char *git_dir;
const char *sha1_dir;
const char *template_dir = NULL;
+ char *repo_dir = NULL;
char *path;
- int len, i, reinit;
+ int len, i, reinit, workdir_fd;
int quiet = 0;
for (i = 1; i < argc; i++, argv++) {
@@ -337,7 +338,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
shared_repository = git_config_perm("arg", arg+9);
else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet"))
quiet = 1;
- else
+ else if (!prefixcmp(arg, "--workdir-for=")) {
+ repo_dir = xmalloc(PATH_MAX);
+ strcpy(repo_dir, arg+14);
+ } else
usage(init_db_usage);
}
@@ -406,11 +410,48 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
git_config_set("receive.denyNonFastforwards", "true");
}
- if (!quiet)
- printf("%s%s Git repository in %s/\n",
+ if (repo_dir) {
+ len = strlen(git_dir);
+ memcpy(path, git_dir, len);
+ strcpy(path+len, "/workdir_for");
+ len = strlen(repo_dir);
+#ifdef __MINGW32__
+ for(i = 0; i < len; ++i) {
+ if (repo_dir[i] == '\\')
+ repo_dir[i] = '/';
+ }
+#endif
+ if (!is_git_directory(repo_dir)) {
+ strcpy(repo_dir+len, "/.git");
+ if (!is_git_directory(repo_dir))
+ die("specified --workdir-for path is not a git repository (%s)", repo_dir);
+ }
+ workdir_fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0666);
+ if (!workdir_fd)
+ die("couldn't create workdir redirection file: %s", strerror(errno));
+ write_or_die(workdir_fd, repo_dir, strlen(repo_dir));
+ if (close(workdir_fd) < 0)
+ die("closing file %s: %s", path, strerror(errno));
+
+ /* Copy current HEAD */
+ strcpy(repo_dir+len, "/HEAD");
+ len = strlen(git_dir);
+ strcpy(path+len, "/HEAD");
+ copy_file(path, repo_dir, 0);
+
+ /* Should force a checkout of the current HEAD. Oh well.. */
+ }
+
+ if (!quiet) {
+ printf("%s%s %s repository in %s/\n",
reinit ? "Reinitialized existing" : "Initialized empty",
shared_repository ? " shared" : "",
+ repo_dir ? "workdir" : "Git",
git_dir);
-
+ if (repo_dir)
+ printf("You now either need to do a 'git reset --hard', or force a switch to another branch.\n");
+ }
+ if (repo_dir)
+ free(repo_dir);
return 0;
}
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 90dbb9d..d83ba59 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -511,6 +511,25 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
printf("%s/.git\n", cwd);
continue;
}
+ if (!strcmp(arg, "--git-redirection-dir")) {
+ const char *redir = get_git_redirection_dir();
+ printf("%s\n", redir ? redir
+ : "");
+ continue;
+ }
+ if (!strcmp(arg, "--git-object-dir")) {
+ printf("%s\n", get_object_directory());
+ continue;
+ }
+ if (!strcmp(arg, "--git-refs-dir")) {
+ printf("%s\n", get_refs_directory());
+ continue;
+ }
+ if (!strcmp(arg, "--uses-git-redirection")) {
+ printf("%s\n", get_git_redirection_dir() ? "true"
+ : "false");
+ continue;
+ }
if (!strcmp(arg, "--is-inside-git-dir")) {
printf("%s\n", is_inside_git_dir() ? "true"
: "false");
diff --git a/cache.h b/cache.h
index 660ea04..e8b6879 100644
--- a/cache.h
+++ b/cache.h
@@ -301,6 +301,7 @@ static inline enum object_type object_type(unsigned int mode)
extern int is_bare_repository_cfg;
extern int is_bare_repository(void);
extern int is_inside_git_dir(void);
+extern int is_git_directory(const char *suspect);
extern char *git_work_tree_cfg;
extern int is_inside_work_tree(void);
extern const char *get_git_dir(void);
@@ -310,6 +311,7 @@ extern char *get_index_file(void);
extern char *get_graft_file(void);
extern int set_git_dir(const char *path);
extern const char *get_git_work_tree(void);
+extern const char *get_git_redirection_dir(void);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
diff --git a/environment.c b/environment.c
index 6739a3f..74391de 100644
--- a/environment.c
+++ b/environment.c
@@ -44,7 +44,7 @@ char *git_work_tree_cfg;
static const char *work_tree;
static const char *git_dir;
-static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
+static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file, *git_workdir_redirection;
static void setup_git_env(void)
{
@@ -53,15 +53,12 @@ static void setup_git_env(void)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
git_object_dir = getenv(DB_ENVIRONMENT);
if (!git_object_dir) {
- git_object_dir = xmalloc(strlen(git_dir) + 9);
- sprintf(git_object_dir, "%s/objects", git_dir);
+ git_object_dir = xstrdup(git_path("objects"));
}
- git_refs_dir = xmalloc(strlen(git_dir) + 6);
- sprintf(git_refs_dir, "%s/refs", git_dir);
+ git_refs_dir = xstrdup(git_path("refs"));
git_index_file = getenv(INDEX_ENVIRONMENT);
if (!git_index_file) {
- git_index_file = xmalloc(strlen(git_dir) + 7);
- sprintf(git_index_file, "%s/index", git_dir);
+ git_index_file = xstrdup(git_path("index"));
}
git_graft_file = getenv(GRAFT_ENVIRONMENT);
if (!git_graft_file)
@@ -101,6 +98,58 @@ const char *get_git_work_tree(void)
return work_tree;
}
+static char *workdir_for = "/workdir_for";
+const char *get_git_redirection_dir(void)
+{
+ static int checked_for_redirection = 0;
+ if (!checked_for_redirection && git_dir) {
+ char *buf;
+ struct stat st;
+ int fd;
+ size_t len;
+ int gitdirlen = strlen(git_dir);
+ int workdirlen = strlen(workdir_for);
+
+ checked_for_redirection = 1;
+
+ /* Check if we have a .git/workdir_for redirection file */
+ buf = xmalloc(gitdirlen + workdirlen + 1);
+ memcpy(buf, git_dir, gitdirlen);
+ memcpy(buf + gitdirlen, workdir_for, strlen(workdir_for));
+ buf[gitdirlen + workdirlen] = '\0';
+
+ if (stat(buf, &st) || !S_ISREG(st.st_mode)) {
+ free(buf);
+ return 0;
+ }
+
+ /* Read the 1st line of the file */
+ fd = open(buf, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Error opening %s: %s", buf, strerror(errno));
+ free(buf);
+ return 0;
+ }
+ buf = xrealloc(buf, st.st_size + 1);
+ len = read_in_full(fd, buf, st.st_size);
+ close(fd);
+ buf[len] = '\0';
+
+ if (len != st.st_size)
+ fprintf(stderr, "Error reading .git%s", workdir_for);
+
+ if (len < 4 || !is_git_directory(buf)) {
+ fprintf(stderr, ".git%s pointing to a non-proper git repo path '%s'\n", workdir_for, buf);
+ free(buf);
+ return 0;
+ }
+
+ git_workdir_redirection = buf;
+ /* buf not freed, since redirected_gitpath now points to it */
+ }
+ return git_workdir_redirection;
+}
+
char *get_object_directory(void)
{
if (!git_object_dir)
diff --git a/path.c b/path.c
index 4260952..f6332d6 100644
--- a/path.c
+++ b/path.c
@@ -46,12 +46,28 @@ char *mkpath(const char *fmt, ...)
return cleanup_path(pathname);
}
+static char *redirection_paths[] = { "config", "refs" ,"logs/refs", "objects", "info", "hooks", "packed-refs", "remotes", "rr-cache", 0 };
+static const char *get_redirected_dir(const char *req_path)
+{
+ int i = 0;
+ const char *redir = get_git_redirection_dir();
+ if (redir) {
+ do {
+ if (!memcmp(req_path, redirection_paths[i], strlen(redirection_paths[i]))) {
+ /* fprintf(stderr, "Looking for '%s', returning in '%s' instead of workdir/.git '%s'\n", req_path, redir, get_git_dir()); */
+ return redir;
+ }
+ } while(redirection_paths[++i]);
+ }
+ return 0;
+}
+
char *git_path(const char *fmt, ...)
{
const char *git_dir = get_git_dir();
char *pathname = get_pathname();
va_list args;
- unsigned len;
+ unsigned len, newlen, rdlen, minlen;
len = strlen(git_dir);
if (len > PATH_MAX-100)
@@ -60,10 +76,25 @@ char *git_path(const char *fmt, ...)
if (len && git_dir[len-1] != '/')
pathname[len++] = '/';
va_start(args, fmt);
- len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
+ newlen = len + vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
va_end(args);
- if (len >= PATH_MAX)
+ if (newlen >= PATH_MAX)
return bad_path;
+
+ { /* Redirect certain files when in a workdir */
+ const char *redir = get_redirected_dir(pathname + len);
+ if (redir) {
+ char *pathname_redir = get_pathname();
+ rdlen = strlen(redir);
+ memcpy(pathname_redir, redir, rdlen);
+ if (rdlen && redir[rdlen-1] != '/')
+ pathname_redir[rdlen++] = '/';
+ minlen = MIN(PATH_MAX-rdlen, strlen(pathname+len));
+ memcpy(pathname_redir+rdlen, pathname+len, minlen);
+ pathname_redir[rdlen + minlen] = '\0';
+ pathname = pathname_redir;
+ }
+ }
return cleanup_path(pathname);
}
diff --git a/setup.c b/setup.c
index 89c81e5..2c507d5 100644
--- a/setup.c
+++ b/setup.c
@@ -221,7 +221,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
* a proper "ref:", or a regular file HEAD that has a properly
* formatted sha1 object name.
*/
-static int is_git_directory(const char *suspect)
+int is_git_directory(const char *suspect)
{
char path[PATH_MAX];
size_t len = strlen(suspect);
--
1.5.4.3.394.ga38b
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 12:27 '.git file' alternative, native (cross-platform) workdir support Marius Storm-Olsen
@ 2008-02-29 12:54 ` Johannes Schindelin
2008-02-29 13:24 ` Marius Storm-Olsen
2008-02-29 20:02 ` Junio C Hamano
0 siblings, 2 replies; 8+ messages in thread
From: Johannes Schindelin @ 2008-02-29 12:54 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: Git Mailing List, msysGit
Hi,
On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
> I just caught a glimpse of the '.git file' efforts, as a file for
> redirection to a real repository.
>
> As far as I can tell, the reason for adding the support is to in the end
> provide a cross-platform way of supporting workdirs. (If this is not the
> [main] point, please point me to the thread describing the real reason,
> I couldn't find it.)
This is the main reason, yes.
However, you can also use the .git file to separate the working directory
from the repository, say, on two different drives, when you do not have
symbolic links.
> However, wouldn't simply redirecting everything into a real repo then
> create problems with shared index file and more? A problem which could
> be tacled by file suffixes or other methods, I'm sure, but which would
> require even more patches to achieve the goal.
Not only would it requre these patches, but it would actually make a
_safe_ multiple-workdirs feature possible.
ATM the problem is that you can change a ref that is checked out
elsewhere, and if you are not a Git expert, it will just make your life
miserable.
However, if we do not pretend to have different repositories, but actually
use the _identical_ repository for multiple working directories, we can
make the mechanisms safe!
This is basically the reason why I do not like the current new-workdir
script (and the patch in my private tree where I taught git-branch about
it).
So while your approach may seem easier in the short run, there is no way
you can make it safe. No way, except going the full nine yards, and
actually use the same repository, which means that you have to have the
"other patches", too.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 12:54 ` Johannes Schindelin
@ 2008-02-29 13:24 ` Marius Storm-Olsen
2008-02-29 14:14 ` Jakub Narebski
2008-02-29 14:25 ` Johannes Schindelin
2008-02-29 20:02 ` Junio C Hamano
1 sibling, 2 replies; 8+ messages in thread
From: Marius Storm-Olsen @ 2008-02-29 13:24 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Git Mailing List, msysGit
[-- Attachment #1: Type: text/plain, Size: 2800 bytes --]
Johannes Schindelin said the following on 29.02.2008 13:54:
> On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
>> However, wouldn't simply redirecting everything into a real repo
>> then create problems with shared index file and more? A problem
>> which could be tacled by file suffixes or other methods, I'm
>> sure, but which would require even more patches to achieve the
>> goal.
>
> Not only would it requre these patches, but it would actually make
> a _safe_ multiple-workdirs feature possible.
>
> ATM the problem is that you can change a ref that is checked out
> elsewhere, and if you are not a Git expert, it will just make your
> life miserable.
>
> However, if we do not pretend to have different repositories, but
> actually use the _identical_ repository for multiple working
> directories, we can make the mechanisms safe!
>
> This is basically the reason why I do not like the current
> new-workdir script (and the patch in my private tree where I taught
> git-branch about it).
>
> So while your approach may seem easier in the short run, there is
> no way you can make it safe. No way, except going the full nine
> yards, and actually use the same repository, which means that you
> have to have the "other patches", too.
Sure, I'm aware of that. The initial goal was to make something which
works as the current contrib/workdir/git-new-workdir, just
cross-platform. Then we can take it from there, step by step, until we
have something which works safely; instead of taking a single big leap.
I'm actually not sure that it's impossible to make it safe.
My implementation works by redirecting files into the real repo.
However, we can also detect when redirection is in effect, and do
extra 'maintainance' things then, to avoid the bad effects.
For example, when setting up a workdir, we could duplicate
<real repo>/.git/refs/*
into <real repo>/.git/refs/workdir-<sha1>/*
(<sha1> being the sha1 of the abs path to the workdir)
and have the redirection mechanism redirect all git_path("refs/*") to
the duplicated locations. That way, when pulling in the workdir, it
wouldn't create havok with the real repo's refs. Then in the real
repo, you can easily refer to the refs in from the workdir too, when
you need to.
There are several possibilities here. Since file redirection works
from the beginning, we have a place to start, which can slowly migrate
into whatever. When you think about it, my approach is kinda similar
to the '.git file' approach, just that I don't redirect everything
from the start, just parts to make it work as today on Linux. In the
end my technique could also redirect everything into the real repo,
giving you the same effect as the '.git file'.
--
.marius
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 13:24 ` Marius Storm-Olsen
@ 2008-02-29 14:14 ` Jakub Narebski
2008-02-29 14:25 ` Johannes Schindelin
1 sibling, 0 replies; 8+ messages in thread
From: Jakub Narebski @ 2008-02-29 14:14 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: Johannes Schindelin, Git Mailing List, msysGit
Marius Storm-Olsen <marius@trolltech.com> writes:
> Johannes Schindelin said the following on 29.02.2008 13:54:
>> On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
>>>
>>> However, wouldn't simply redirecting everything into a real repo
>>> then create problems with shared index file and more? A problem
>>> which could be tacled by file suffixes or other methods, I'm
>>> sure, but which would require even more patches to achieve the
>>> goal.
>>
>> Not only would it requre these patches, but it would actually make
>> a _safe_ multiple-workdirs feature possible.
>> ATM the problem is that you can change a ref that is checked out
>> elsewhere, and if you are not a Git expert, it will just make your
>> life miserable.
>> However, if we do not pretend to have different repositories, but
>> actually use the _identical_ repository for multiple working
>> directories, we can make the mechanisms safe!
>> This is basically the reason why I do not like the current
>> new-workdir script (and the patch in my private tree where I taught
>> git-branch about it).
>
> Sure, I'm aware of that. The initial goal was to make something which
> works as the current contrib/workdir/git-new-workdir, just
> cross-platform. Then we can take it from there, step by step, until we
> have something which works safely; instead of taking a single big leap.
>
> I'm actually not sure that it's impossible to make it safe.
> My implementation works by redirecting files into the real
> repo. However, we can also detect when redirection is in effect, and
> do extra 'maintainance' things then, to avoid the bad effects.
>
> For example, when setting up a workdir, we could duplicate
> <real repo>/.git/refs/*
> into <real repo>/.git/refs/workdir-<sha1>/*
> (<sha1> being the sha1 of the abs path to the workdir)
> and have the redirection mechanism redirect all git_path("refs/*") to
> the duplicated locations. That way, when pulling in the workdir, it
> wouldn't create havok with the real repo's refs. Then in the real
> repo, you can easily refer to the refs in from the workdir too, when
> you need to.
I have had yet another idea, namely of shadow / unionfs-alike, which I
have abandoned due to perceived difficulties in implementing it. But
perhaps this would be the best solution for multiple working
directories problem.
The idea is to add core.gitdir variable to the config, which would
point to "master" (main) GIT_DIR.
When requesting any file from repository, be it .git/refs/HEAD,
.git/index, .git/refs/heads/master or any other file, git would first
try to find it in the current GIT_DIR, as existing heuristics find it,
and if not found try with GIT_DIR set to core.gitdir. When trying to
create any file, git would check if directories / path leading to file
in GIT_DIR exists, and if not create it under GIT_DIR set to
core.gitdir.
The only exception would be config file, where current GIT_DIR config
would be fourth layer, on top of system-wide config, global (per-user)
config and core.gitdir config.
What do you think of this idea?
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 13:24 ` Marius Storm-Olsen
2008-02-29 14:14 ` Jakub Narebski
@ 2008-02-29 14:25 ` Johannes Schindelin
2008-02-29 14:51 ` Marius Storm-Olsen
1 sibling, 1 reply; 8+ messages in thread
From: Johannes Schindelin @ 2008-02-29 14:25 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: Git Mailing List, msysGit
Hi,
On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
> Johannes Schindelin said the following on 29.02.2008 13:54:
> > On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
> > > However, wouldn't simply redirecting everything into a real repo
> > > then create problems with shared index file and more? A problem
> > > which could be tacled by file suffixes or other methods, I'm sure,
> > > but which would require even more patches to achieve the goal.
> >
> > Not only would it requre these patches, but it would actually make a
> > _safe_ multiple-workdirs feature possible.
>
> Sure, I'm aware of that. The initial goal was to make something which
> works as the current contrib/workdir/git-new-workdir, just
> cross-platform. Then we can take it from there, step by step, until we
> have something which works safely; instead of taking a single big leap.
That's what I am saying: there is no way to make it safe.
> I'm actually not sure that it's impossible to make it safe. My
> implementation works by redirecting files into the real repo. However,
> we can also detect when redirection is in effect, and do extra
> 'maintainance' things then, to avoid the bad effects.
>From the perspective of Windows, I guess it is easy to overlook the fact
that permissions can break your idea.
Even after creating a second working tree for an existing repository, the
permissions of the original repository can change.
The only way to be on the safe side is to use _the repository_ twice. IOW
not having a second .git/ directory.
Also, having a single .git is just a very simple, and thus preferable
concept, to having part of this, and part of that repository.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 14:25 ` Johannes Schindelin
@ 2008-02-29 14:51 ` Marius Storm-Olsen
0 siblings, 0 replies; 8+ messages in thread
From: Marius Storm-Olsen @ 2008-02-29 14:51 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Git Mailing List, msysGit
[-- Attachment #1: Type: text/plain, Size: 1958 bytes --]
Johannes Schindelin said the following on 29.02.2008 15:25:
> On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
>> I'm actually not sure that it's impossible to make it safe. My
>> implementation works by redirecting files into the real repo.
>> However, we can also detect when redirection is in effect, and do
>> extra 'maintainance' things then, to avoid the bad effects.
>
> From the perspective of Windows, I guess it is easy to overlook the
> fact that permissions can break your idea.
>
> Even after creating a second working tree for an existing
> repository, the permissions of the original repository can change.
Sure, but that would break _any_ working tree implementation. Without
access to the original data, it whole thing is bust, no matter if you
redirect all or part of .git/.
Checking if we have access to the redirected .git is trivial in both
cases. (partial or whole redirection)
> The only way to be on the safe side is to use _the repository_
> twice. IOW not having a second .git/ directory.
>
> Also, having a single .git is just a very simple, and thus
> preferable concept, to having part of this, and part of that
> repository.
I whole heartedly agree. I'm not proposing to keep it split in the
long run. I'm just proposing something that 'works' *now*, and can be
improved incrementally; as opposed to, doesn't work now, and needs to
be fully implemented before it works for the Windows crowd.
PS. The redirection method I propose already alleviates an issue of
the current git-new-workdir has, which Shawn has experienced many
atime: The deletion of .git/config and .git/packed-refs, making
'git-config' and 'git tag -d' unsafe in a workdir. (Though I'm unsure
if that has been fixed already. In any case, since the files are
really redirected, there no chance that deleting a file will remove a
synlink, only to be recreated as a normal file instead)
--
.marius
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 12:54 ` Johannes Schindelin
2008-02-29 13:24 ` Marius Storm-Olsen
@ 2008-02-29 20:02 ` Junio C Hamano
2008-02-29 21:32 ` Marius Storm-Olsen
1 sibling, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2008-02-29 20:02 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Marius Storm-Olsen, Git Mailing List, msysGit
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> On Fri, 29 Feb 2008, Marius Storm-Olsen wrote:
>
>> I just caught a glimpse of the '.git file' efforts, as a file for
>> redirection to a real repository.
>>
>> As far as I can tell, the reason for adding the support is to in the end
>> provide a cross-platform way of supporting workdirs. (If this is not the
>> [main] point, please point me to the thread describing the real reason,
>> I couldn't find it.)
>
> This is the main reason, yes.
I do not think so. For repository and work tree separation, we already
have core.worktree. Multiple work trees attached to a single repository
is what contrib/workdir/ does, and it could probably be extended, but that
one needs more than "redirect .git elsewhere".
The primary reason we may want to do the ".git file" thing is to sanely
support switching between branches (or checking out a different revision,
which amounts to the same thing) when one has a submodule and the other
one either does not have that submodule anywhere or have it in a different
location in its tree.
Suppose the HEAD one binds a submodule "gitk" at gitk-git. Then suppose
we want to switch to an old branch that did not have that submodule bound
yet. Or the branch we are switching to has the submodule at modules/gitk.
What happens?
Currently, when we are on HEAD, we create a directory at gitk-git and make
gitk-git/.git directory its controlling repository (i.e. GIT_DIR).
Switching to a branch that did not have the submodule bound will need to
rmdir gitk-git (this needs to happen no matter what) but as a side effect
we will lose gitk-git/.git repository. Switching back to where we were
would require reloading that repository from somewhere else, but if you
are "the upstream", that somewhere else may not even exist.
One way to solve this would be to add .git/submodules/paulus.git
repository inside the controlling reopsitory of the toplevel project, and
point that with the ".git file" installed at gitk-git/.git, when we are on
HEAD. We can lose gitk-git directory and everything below it when
switching away from the revision, but when we come back, we can recreate
gitk-git directory, point gitk-git/.git back to .git/submodules/paulus.git
kept in the toplevel repository, and check the appropriate commit out there.
After switching to an old revision that did not have the submodule,
further switching to a branch that has the submodule at modules/gitk would
be the same deal. Instead of creating gitk-git directory and installing
the ".git file" there (which is what we did when we came back to the
original HEAD), create modules/gitk and install the ".git file" there, to
point at the same .git/submodules/paulus.git/.
We should be able to do this today without ".git file" using symlinks.
It's just a Porcelain hackery, so I'll leave it to interested parties as
an exercise.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: '.git file' alternative, native (cross-platform) workdir support.
2008-02-29 20:02 ` Junio C Hamano
@ 2008-02-29 21:32 ` Marius Storm-Olsen
0 siblings, 0 replies; 8+ messages in thread
From: Marius Storm-Olsen @ 2008-02-29 21:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List, msysGit
[-- Attachment #1: Type: text/plain, Size: 3056 bytes --]
Junio C Hamano wrote:
> The primary reason we may want to do the ".git file" thing is to
> sanely support switching between branches (or checking out a
> different revision, which amounts to the same thing) when one has a
> submodule and the other one either does not have that submodule
> anywhere or have it in a different location in its tree.
...
> One way to solve this would be to add .git/submodules/paulus.git
> repository inside the controlling reopsitory of the toplevel project,
> and point that with the ".git file" installed at gitk-git/.git, when
> we are on HEAD. We can lose gitk-git directory and everything below
> it when switching away from the revision, but when we come back, we
> can recreate gitk-git directory, point gitk-git/.git back to
> .git/submodules/paulus.git kept in the toplevel repository, and check
> the appropriate commit out there.
>
> After switching to an old revision that did not have the submodule,
> further switching to a branch that has the submodule at modules/gitk
> would be the same deal. Instead of creating gitk-git directory and
> installing the ".git file" there (which is what we did when we came
> back to the original HEAD), create modules/gitk and install the ".git
> file" there, to point at the same .git/submodules/paulus.git/.
Ahh, ok, this makes sense. *Then* you need to point all of .git to a
specific location. But, in this case you're not interested in keeping
n-different states, as we are in a multiple workdir situation. So, it's
a much easier case.
The question is, is this also the appropriate basis for solving the
multiple workdir case? If so, we need to come up with a scheme that lets
us keep n number of states inside one single .git structure. Is this
reasonable? It's not like it's too hard, just a bit messy.
The reason I ask is to evaluate if I should cleanup the patch I did for
the native workdir support that started out this thread, or just lay it
dead for the '.git file' solution which still would need a lot of work
before it's finished. (Though, as I said before, my redirection way
could certainly migrate into a '.git file' solution over time)
I basically just need a certain amount of knowledgeable people to either
say 'drop it' or 'roll with it'.. I'm ambivalent, though I want workdirs
on Windows yesterday. :-)
So, I guess I have Dscho's -1, and my own +1 = 0 :-p
> We should be able to do this today without ".git file" using
> symlinks. It's just a Porcelain hackery, so I'll leave it to
> interested parties as an exercise.
Symlinks wouldn't really work, unless you force people to always keep
their full .git next to the workdir. So, multiple workdirs with
submodules would then fail, as would FS without symlink support (duh).
This seems to be the issue with the current '.git file' implementation
as well. If the repo is not located next to the workdir, it will fail.
Or am I reading the code incorrectly? And what happens with recursive
submodules?
--
.marius
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-02-29 21:33 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-29 12:27 '.git file' alternative, native (cross-platform) workdir support Marius Storm-Olsen
2008-02-29 12:54 ` Johannes Schindelin
2008-02-29 13:24 ` Marius Storm-Olsen
2008-02-29 14:14 ` Jakub Narebski
2008-02-29 14:25 ` Johannes Schindelin
2008-02-29 14:51 ` Marius Storm-Olsen
2008-02-29 20:02 ` Junio C Hamano
2008-02-29 21:32 ` Marius Storm-Olsen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).