Skip to content

Commit 055e1e2

Browse files
committed
Merge branch 'jl/maint-submodule-gitfile-awareness'
* jl/maint-submodule-gitfile-awareness: Teach diff --submodule and status to handle .git files in submodules
2 parents 3b0c196 + eee49b6 commit 055e1e2

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

submodule.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@ static int add_submodule_odb(const char *path)
1212
struct strbuf objects_directory = STRBUF_INIT;
1313
struct alternate_object_database *alt_odb;
1414
int ret = 0;
15+
const char *git_dir;
1516

16-
strbuf_addf(&objects_directory, "%s/.git/objects/", path);
17+
strbuf_addf(&objects_directory, "%s/.git", path);
18+
git_dir = read_gitfile_gently(objects_directory.buf);
19+
if (git_dir) {
20+
strbuf_reset(&objects_directory);
21+
strbuf_addstr(&objects_directory, git_dir);
22+
}
23+
strbuf_addstr(&objects_directory, "/objects/");
1724
if (!is_directory(objects_directory.buf)) {
1825
ret = -1;
1926
goto done;
@@ -132,7 +139,6 @@ void show_submodule_summary(FILE *f, const char *path,
132139

133140
unsigned is_submodule_modified(const char *path, int ignore_untracked)
134141
{
135-
int i;
136142
ssize_t len;
137143
struct child_process cp;
138144
const char *argv[] = {
@@ -141,38 +147,33 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
141147
NULL,
142148
NULL,
143149
};
144-
const char *env[LOCAL_REPO_ENV_SIZE + 3];
145150
struct strbuf buf = STRBUF_INIT;
146151
unsigned dirty_submodule = 0;
147152
const char *line, *next_line;
153+
const char *git_dir;
148154

149-
for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++)
150-
env[i] = local_repo_env[i];
151-
152-
strbuf_addf(&buf, "%s/.git/", path);
153-
if (!is_directory(buf.buf)) {
155+
strbuf_addf(&buf, "%s/.git", path);
156+
git_dir = read_gitfile_gently(buf.buf);
157+
if (!git_dir)
158+
git_dir = buf.buf;
159+
if (!is_directory(git_dir)) {
154160
strbuf_release(&buf);
155161
/* The submodule is not checked out, so it is not modified */
156162
return 0;
157163

158164
}
159165
strbuf_reset(&buf);
160166

161-
strbuf_addf(&buf, "GIT_WORK_TREE=%s", path);
162-
env[i++] = strbuf_detach(&buf, NULL);
163-
strbuf_addf(&buf, "GIT_DIR=%s/.git", path);
164-
env[i++] = strbuf_detach(&buf, NULL);
165-
env[i] = NULL;
166-
167167
if (ignore_untracked)
168168
argv[2] = "-uno";
169169

170170
memset(&cp, 0, sizeof(cp));
171171
cp.argv = argv;
172-
cp.env = env;
172+
cp.env = local_repo_env;
173173
cp.git_cmd = 1;
174174
cp.no_stdin = 1;
175175
cp.out = -1;
176+
cp.dir = path;
176177
if (start_command(&cp))
177178
die("Could not run git status --porcelain");
178179

@@ -201,8 +202,6 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
201202
if (finish_command(&cp))
202203
die("git status --porcelain failed");
203204

204-
for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++)
205-
free((char *)env[i]);
206205
strbuf_release(&buf);
207206
return dirty_submodule;
208207
}

t/t4041-diff-submodule.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,4 +329,19 @@ index 0000000..$head7
329329
EOF
330330
"
331331

332+
test_expect_success 'setup .git file for sm2' '
333+
(cd sm2 &&
334+
REAL="$(pwd)/../.real" &&
335+
mv .git "$REAL"
336+
echo "gitdir: $REAL" >.git)
337+
'
338+
339+
test_expect_success 'diff --submodule with .git file' '
340+
git diff --submodule HEAD^ >actual &&
341+
diff actual - <<-EOF
342+
Submodule sm1 $head6...0000000 (submodule deleted)
343+
Submodule sm2 0000000...$head7 (new submodule)
344+
EOF
345+
'
346+
332347
test_done

t/t7506-status-submodule.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ test_expect_success 'status with added and untracked file in modified submodule
157157
EOF
158158
'
159159

160+
test_expect_success 'setup .git file for sub' '
161+
(cd sub &&
162+
rm -f new-file
163+
REAL="$(pwd)/../.real" &&
164+
mv .git "$REAL"
165+
echo "gitdir: $REAL" >.git) &&
166+
echo .real >>.gitignore &&
167+
git commit -m "added .real to .gitignore" .gitignore
168+
'
169+
170+
test_expect_success 'status with added file in modified submodule with .git file' '
171+
(cd sub && git reset --hard && echo >foo && git add foo) &&
172+
git status >output &&
173+
grep "modified: sub (new commits, modified content)" output
174+
'
175+
160176
test_expect_success 'rm submodule contents' '
161177
rm -rf sub/* sub/.git
162178
'

0 commit comments

Comments
 (0)