Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
f623cf89
Commit
f623cf89
authored
Mar 22, 2017
by
Edward Thomson
Committed by
GitHub
Mar 22, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4163 from pks-t/pks/submodules-with-worktrees
Worktree fixes
parents
6fd6c678
b0c9bc92
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
300 additions
and
135 deletions
+300
-135
include/git2/worktree.h
+12
-0
src/refdb_fs.c
+8
-2
src/submodule.c
+18
-6
src/worktree.c
+108
-40
src/worktree.h
+1
-1
tests/resources/submodules/testrepo/.gitted/config
+0
-3
tests/worktree/open.c
+30
-81
tests/worktree/refs.c
+26
-0
tests/worktree/submodule.c
+92
-0
tests/worktree/worktree.c
+5
-2
No files found.
include/git2/worktree.h
View file @
f623cf89
...
...
@@ -44,6 +44,18 @@ GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo);
GIT_EXTERN
(
int
)
git_worktree_lookup
(
git_worktree
**
out
,
git_repository
*
repo
,
const
char
*
name
);
/**
* Open a worktree of a given repository
*
* If a repository is not the main tree but a worktree, this
* function will look up the worktree inside the parent
* repository and create a new `git_worktree` structure.
*
* @param out Out-pointer for the newly allocated worktree
* @param repo Repository to look up worktree for
*/
GIT_EXTERN
(
int
)
git_worktree_open_from_repository
(
git_worktree
**
out
,
git_repository
*
repo
);
/**
* Free a previously allocated worktree
*
* @param wt worktree handle to close. If NULL nothing occurs.
...
...
src/refdb_fs.c
View file @
f623cf89
...
...
@@ -739,6 +739,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
{
int
error
,
filebuf_flags
;
git_buf
ref_path
=
GIT_BUF_INIT
;
const
char
*
basedir
;
assert
(
file
&&
backend
&&
name
);
...
...
@@ -747,13 +748,18 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
return
GIT_EINVALIDSPEC
;
}
if
(
is_per_worktree_ref
(
name
))
basedir
=
backend
->
gitpath
;
else
basedir
=
backend
->
commonpath
;
/* Remove a possibly existing empty directory hierarchy
* which name would collide with the reference name
*/
if
((
error
=
git_futils_rmdir_r
(
name
,
ba
ckend
->
gitpath
,
GIT_RMDIR_SKIP_NONEMPTY
))
<
0
)
if
((
error
=
git_futils_rmdir_r
(
name
,
ba
sedir
,
GIT_RMDIR_SKIP_NONEMPTY
))
<
0
)
return
error
;
if
(
git_buf_joinpath
(
&
ref_path
,
ba
ckend
->
gitpath
,
name
)
<
0
)
if
(
git_buf_joinpath
(
&
ref_path
,
ba
sedir
,
name
)
<
0
)
return
-
1
;
filebuf_flags
=
GIT_FILEBUF_FORCE
;
...
...
src/submodule.c
View file @
f623cf89
...
...
@@ -22,6 +22,7 @@
#include "iterator.h"
#include "path.h"
#include "index.h"
#include "worktree.h"
#define GIT_MODULES_FILE ".gitmodules"
...
...
@@ -2038,17 +2039,28 @@ static int lookup_default_remote(git_remote **remote, git_repository *repo)
static
int
get_url_base
(
git_buf
*
url
,
git_repository
*
repo
)
{
int
error
;
git_worktree
*
wt
=
NULL
;
git_remote
*
remote
=
NULL
;
if
(
!
(
error
=
lookup_default_remote
(
&
remote
,
repo
))
)
{
if
(
(
error
=
lookup_default_remote
(
&
remote
,
repo
))
==
0
)
{
error
=
git_buf_sets
(
url
,
git_remote_url
(
remote
));
g
it_remote_free
(
remote
)
;
}
else
if
(
error
==
GIT_ENOTFOUND
)
{
/* if repository does not have a default remote, use workdir instead */
g
oto
out
;
}
else
if
(
error
!=
GIT_ENOTFOUND
)
goto
out
;
else
giterr_clear
();
/* if repository does not have a default remote, use workdir instead */
if
(
git_repository_is_worktree
(
repo
))
{
if
((
error
=
git_worktree_open_from_repository
(
&
wt
,
repo
))
<
0
)
goto
out
;
error
=
git_buf_sets
(
url
,
wt
->
parent_path
);
}
else
error
=
git_buf_sets
(
url
,
git_repository_workdir
(
repo
));
}
out:
git_remote_free
(
remote
);
git_worktree_free
(
wt
);
return
error
;
}
...
...
src/worktree.c
View file @
f623cf89
...
...
@@ -14,11 +14,20 @@
#include "repository.h"
#include "worktree.h"
static
bool
is_worktree_dir
(
git_buf
*
dir
)
static
bool
is_worktree_dir
(
const
char
*
dir
)
{
return
git_path_contains_file
(
dir
,
"commondir"
)
&&
git_path_contains_file
(
dir
,
"gitdir"
)
&&
git_path_contains_file
(
dir
,
"HEAD"
);
git_buf
buf
=
GIT_BUF_INIT
;
int
error
;
if
(
git_buf_sets
(
&
buf
,
dir
)
<
0
)
return
-
1
;
error
=
git_path_contains_file
(
&
buf
,
"commondir"
)
&&
git_path_contains_file
(
&
buf
,
"gitdir"
)
&&
git_path_contains_file
(
&
buf
,
"HEAD"
);
git_buf_free
(
&
buf
);
return
error
;
}
int
git_worktree_list
(
git_strarray
*
wts
,
git_repository
*
repo
)
...
...
@@ -47,7 +56,7 @@ int git_worktree_list(git_strarray *wts, git_repository *repo)
git_buf_truncate
(
&
path
,
len
);
git_buf_puts
(
&
path
,
worktree
);
if
(
!
is_worktree_dir
(
&
path
))
{
if
(
!
is_worktree_dir
(
path
.
ptr
))
{
git_vector_remove
(
&
worktrees
,
i
);
git__free
(
worktree
);
}
...
...
@@ -112,6 +121,46 @@ out:
return
err
;
}
static
int
open_worktree_dir
(
git_worktree
**
out
,
const
char
*
parent
,
const
char
*
dir
,
const
char
*
name
)
{
git_buf
gitdir
=
GIT_BUF_INIT
;
git_worktree
*
wt
=
NULL
;
int
error
=
0
;
if
(
!
is_worktree_dir
(
dir
))
{
error
=
-
1
;
goto
out
;
}
if
((
wt
=
git__calloc
(
1
,
sizeof
(
struct
git_repository
)))
==
NULL
)
{
error
=
-
1
;
goto
out
;
}
if
((
wt
->
name
=
git__strdup
(
name
))
==
NULL
||
(
wt
->
commondir_path
=
git_worktree__read_link
(
dir
,
"commondir"
))
==
NULL
||
(
wt
->
gitlink_path
=
git_worktree__read_link
(
dir
,
"gitdir"
))
==
NULL
||
(
wt
->
parent_path
=
git__strdup
(
parent
))
==
NULL
)
{
error
=
-
1
;
goto
out
;
}
if
((
error
=
git_path_prettify_dir
(
&
gitdir
,
dir
,
NULL
))
<
0
)
goto
out
;
wt
->
gitdir_path
=
git_buf_detach
(
&
gitdir
);
wt
->
locked
=
!!
git_worktree_is_locked
(
NULL
,
wt
);
*
out
=
wt
;
out:
if
(
error
)
git_worktree_free
(
wt
);
git_buf_free
(
&
gitdir
);
return
error
;
}
int
git_worktree_lookup
(
git_worktree
**
out
,
git_repository
*
repo
,
const
char
*
name
)
{
git_buf
path
=
GIT_BUF_INIT
;
...
...
@@ -125,33 +174,47 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na
if
((
error
=
git_buf_printf
(
&
path
,
"%s/worktrees/%s"
,
repo
->
commondir
,
name
))
<
0
)
goto
out
;
if
(
!
is_worktree_dir
(
&
path
))
{
error
=
-
1
;
if
((
error
=
(
open_worktree_dir
(
out
,
git_repository_workdir
(
repo
),
path
.
ptr
,
name
)))
<
0
)
goto
out
;
}
if
((
wt
=
git__malloc
(
sizeof
(
struct
git_repository
)))
==
NULL
)
{
out:
git_buf_free
(
&
path
);
if
(
error
)
git_worktree_free
(
wt
);
return
error
;
}
int
git_worktree_open_from_repository
(
git_worktree
**
out
,
git_repository
*
repo
)
{
git_buf
parent
=
GIT_BUF_INIT
;
const
char
*
gitdir
,
*
commondir
;
char
*
name
=
NULL
;
int
error
=
0
;
if
(
!
git_repository_is_worktree
(
repo
))
{
giterr_set
(
GITERR_WORKTREE
,
"cannot open worktree of a non-worktree repo"
);
error
=
-
1
;
goto
out
;
}
if
((
wt
->
name
=
git__strdup
(
name
))
==
NULL
||
(
wt
->
commondir_path
=
git_worktree__read_link
(
path
.
ptr
,
"commondir"
))
==
NULL
||
(
wt
->
gitlink_path
=
git_worktree__read_link
(
path
.
ptr
,
"gitdir"
))
==
NULL
||
(
wt
->
parent_path
=
git__strdup
(
git_repository_path
(
repo
)))
==
NULL
)
{
error
=
-
1
;
gitdir
=
git_repository_path
(
repo
);
commondir
=
git_repository_commondir
(
repo
);
if
((
error
=
git_path_prettify_dir
(
&
parent
,
".."
,
commondir
))
<
0
)
goto
out
;
}
wt
->
gitdir_path
=
git_buf_detach
(
&
path
);
wt
->
locked
=
!!
git_worktree_is_locked
(
NULL
,
wt
);
(
*
out
)
=
wt
;
/* The name is defined by the last component in '.git/worktree/%s' */
name
=
git_path_basename
(
gitdir
);
out:
git_buf_free
(
&
path
)
;
if
((
error
=
open_worktree_dir
(
out
,
parent
.
ptr
,
gitdir
,
name
))
<
0
)
goto
out
;
out:
if
(
error
)
git_worktree_free
(
wt
);
free
(
name
);
git_buf_free
(
&
parent
);
return
error
;
}
...
...
@@ -177,7 +240,7 @@ int git_worktree_validate(const git_worktree *wt)
assert
(
wt
);
git_buf_puts
(
&
buf
,
wt
->
gitdir_path
);
if
(
!
is_worktree_dir
(
&
buf
))
{
if
(
!
is_worktree_dir
(
buf
.
ptr
))
{
giterr_set
(
GITERR_WORKTREE
,
"Worktree gitdir ('%s') is not valid"
,
wt
->
gitlink_path
);
...
...
@@ -209,7 +272,7 @@ out:
int
git_worktree_add
(
git_worktree
**
out
,
git_repository
*
repo
,
const
char
*
name
,
const
char
*
worktree
)
{
git_buf
path
=
GIT_BUF_INIT
,
buf
=
GIT_BUF_INIT
;
git_buf
gitdir
=
GIT_BUF_INIT
,
wddir
=
GIT_BUF_INIT
,
buf
=
GIT_BUF_INIT
;
git_reference
*
ref
=
NULL
,
*
head
=
NULL
;
git_commit
*
commit
=
NULL
;
git_repository
*
wt
=
NULL
;
...
...
@@ -220,35 +283,39 @@ int git_worktree_add(git_worktree **out, git_repository *repo, const char *name,
*
out
=
NULL
;
/* Create
worktree related files in commondir
*/
if
((
err
=
git_buf_joinpath
(
&
path
,
repo
->
commondir
,
"worktrees"
))
<
0
)
/* Create
gitdir directory ".git/worktrees/<name>"
*/
if
((
err
=
git_buf_joinpath
(
&
gitdir
,
repo
->
commondir
,
"worktrees"
))
<
0
)
goto
out
;
if
(
!
git_path_exists
(
path
.
ptr
))
if
((
err
=
git_futils_mkdir
(
path
.
ptr
,
0755
,
GIT_MKDIR_EXCL
))
<
0
)
if
(
!
git_path_exists
(
gitdir
.
ptr
))
if
((
err
=
git_futils_mkdir
(
gitdir
.
ptr
,
0755
,
GIT_MKDIR_EXCL
))
<
0
)
goto
out
;
if
((
err
=
git_buf_joinpath
(
&
gitdir
,
gitdir
.
ptr
,
name
))
<
0
)
goto
out
;
if
((
err
=
git_
buf_joinpath
(
&
path
,
path
.
ptr
,
name
))
<
0
)
if
((
err
=
git_
futils_mkdir
(
gitdir
.
ptr
,
0755
,
GIT_MKDIR_EXCL
))
<
0
)
goto
out
;
if
((
err
=
git_
futils_mkdir
(
path
.
ptr
,
0755
,
GIT_MKDIR_EXC
L
))
<
0
)
if
((
err
=
git_
path_prettify_dir
(
&
gitdir
,
gitdir
.
ptr
,
NUL
L
))
<
0
)
goto
out
;
/* Create worktree work dir */
if
((
err
=
git_futils_mkdir
(
worktree
,
0755
,
GIT_MKDIR_EXCL
))
<
0
)
goto
out
;
if
((
err
=
git_path_prettify_dir
(
&
wddir
,
worktree
,
NULL
))
<
0
)
goto
out
;
/* Create worktree .git file */
if
((
err
=
git_buf_printf
(
&
buf
,
"gitdir: %s
\n
"
,
path
.
ptr
))
<
0
)
if
((
err
=
git_buf_printf
(
&
buf
,
"gitdir: %s
\n
"
,
gitdir
.
ptr
))
<
0
)
goto
out
;
if
((
err
=
write_wtfile
(
w
orktree
,
".git"
,
&
buf
))
<
0
)
if
((
err
=
write_wtfile
(
w
ddir
.
ptr
,
".git"
,
&
buf
))
<
0
)
goto
out
;
/* Create
common
dir files */
if
((
err
=
git_
buf_sets
(
&
buf
,
repo
->
commondir
))
<
0
/* Create
git
dir files */
if
((
err
=
git_
path_prettify_dir
(
&
buf
,
repo
->
commondir
,
NULL
)
<
0
)
||
(
err
=
git_buf_putc
(
&
buf
,
'\n'
))
<
0
||
(
err
=
write_wtfile
(
path
.
ptr
,
"commondir"
,
&
buf
))
<
0
)
||
(
err
=
write_wtfile
(
gitdir
.
ptr
,
"commondir"
,
&
buf
))
<
0
)
goto
out
;
if
((
err
=
git_buf_joinpath
(
&
buf
,
w
orktree
,
".git"
))
<
0
if
((
err
=
git_buf_joinpath
(
&
buf
,
w
ddir
.
ptr
,
".git"
))
<
0
||
(
err
=
git_buf_putc
(
&
buf
,
'\n'
))
<
0
||
(
err
=
write_wtfile
(
path
.
ptr
,
"gitdir"
,
&
buf
))
<
0
)
||
(
err
=
write_wtfile
(
gitdir
.
ptr
,
"gitdir"
,
&
buf
))
<
0
)
goto
out
;
/* Create new branch */
...
...
@@ -260,9 +327,9 @@ int git_worktree_add(git_worktree **out, git_repository *repo, const char *name,
goto
out
;
/* Set worktree's HEAD */
if
((
err
=
git_repository_create_head
(
path
.
ptr
,
name
))
<
0
)
if
((
err
=
git_repository_create_head
(
gitdir
.
ptr
,
git_reference_name
(
ref
)
))
<
0
)
goto
out
;
if
((
err
=
git_repository_open
(
&
wt
,
w
orktree
))
<
0
)
if
((
err
=
git_repository_open
(
&
wt
,
w
ddir
.
ptr
))
<
0
)
goto
out
;
/* Checkout worktree's HEAD */
...
...
@@ -275,7 +342,8 @@ int git_worktree_add(git_worktree **out, git_repository *repo, const char *name,
goto
out
;
out:
git_buf_free
(
&
path
);
git_buf_free
(
&
gitdir
);
git_buf_free
(
&
wddir
);
git_buf_free
(
&
buf
);
git_reference_free
(
ref
);
git_reference_free
(
head
);
...
...
@@ -394,7 +462,7 @@ int git_worktree_prune(git_worktree *wt, unsigned flags)
}
/* Delete gitdir in parent repository */
if
((
err
=
git_buf_printf
(
&
path
,
"%s/worktrees/%s"
,
wt
->
parent
_path
,
wt
->
name
))
<
0
)
if
((
err
=
git_buf_printf
(
&
path
,
"%s/worktrees/%s"
,
wt
->
commondir
_path
,
wt
->
name
))
<
0
)
goto
out
;
if
(
!
git_path_exists
(
path
.
ptr
))
{
...
...
src/worktree.h
View file @
f623cf89
...
...
@@ -24,7 +24,7 @@ struct git_worktree {
/* Path to the common directory contained in the parent
* repository */
char
*
commondir_path
;
/* Path to the parent's
.git
directory */
/* Path to the parent's
working
directory */
char
*
parent_path
;
int
locked
:
1
;
...
...
tests/resources/submodules/testrepo/.gitted/config
View file @
f623cf89
...
...
@@ -4,9 +4,6 @@
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = /Users/rb/src/libgit2/tests/resources/testrepo.git
[branch "master"]
remote = origin
merge = refs/heads/master
tests/worktree/open.c
View file @
f623cf89
#include "clar_libgit2.h"
#include "repository.h"
#include "worktree.h"
#include "worktree_helpers.h"
#define WORKTREE_PARENT "submodules-worktree-parent"
#define WORKTREE_CHILD "submodules-worktree-child"
#define COMMON_REPO "testrepo"
#define WORKTREE_REPO "testrepo-worktree"
static
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
COMMON_REPO
,
WORKTREE_REPO
);
static
void
assert_worktree_valid
(
git_repository
*
wt
,
const
char
*
parentdir
,
const
char
*
wtdir
)
{
git_buf
path
=
GIT_BUF_INIT
;
...
...
@@ -34,56 +35,46 @@ static void assert_worktree_valid(git_repository *wt, const char *parentdir, con
git_buf_free
(
&
path
);
}
void
test_worktree_open__
repository
(
void
)
void
test_worktree_open__
initialize
(
void
)
{
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
COMMON_REPO
,
WORKTREE_REPO
);
setup_fixture_worktree
(
&
fixture
);
}
assert_worktree_valid
(
fixture
.
worktree
,
COMMON_REPO
,
WORKTREE_REPO
);
void
test_worktree_open__cleanup
(
void
)
{
cleanup_fixture_worktree
(
&
fixture
);
}
void
test_worktree_open__repository
(
void
)
{
assert_worktree_valid
(
fixture
.
worktree
,
COMMON_REPO
,
WORKTREE_REPO
);
}
void
test_worktree_open__repository_through_workdir
(
void
)
{
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
COMMON_REPO
,
WORKTREE_REPO
);
git_repository
*
wt
;
setup_fixture_worktree
(
&
fixture
);
cl_git_pass
(
git_repository_open
(
&
wt
,
WORKTREE_REPO
));
assert_worktree_valid
(
wt
,
COMMON_REPO
,
WORKTREE_REPO
);
git_repository_free
(
wt
);
cleanup_fixture_worktree
(
&
fixture
);
}
void
test_worktree_open__repository_through_gitlink
(
void
)
{
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
COMMON_REPO
,
WORKTREE_REPO
);
git_repository
*
wt
;
setup_fixture_worktree
(
&
fixture
);
cl_git_pass
(
git_repository_open
(
&
wt
,
WORKTREE_REPO
"/.git"
));
assert_worktree_valid
(
wt
,
COMMON_REPO
,
WORKTREE_REPO
);
git_repository_free
(
wt
);
cleanup_fixture_worktree
(
&
fixture
);
}
void
test_worktree_open__repository_through_gitdir
(
void
)
{
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
COMMON_REPO
,
WORKTREE_REPO
);
git_buf
gitdir_path
=
GIT_BUF_INIT
;
git_repository
*
wt
;
setup_fixture_worktree
(
&
fixture
);
cl_git_pass
(
git_buf_joinpath
(
&
gitdir_path
,
COMMON_REPO
,
".git"
));
cl_git_pass
(
git_buf_joinpath
(
&
gitdir_path
,
gitdir_path
.
ptr
,
"worktrees"
));
cl_git_pass
(
git_buf_joinpath
(
&
gitdir_path
,
gitdir_path
.
ptr
,
"testrepo-worktree"
));
...
...
@@ -93,18 +84,13 @@ void test_worktree_open__repository_through_gitdir(void)
git_buf_free
(
&
gitdir_path
);
git_repository_free
(
wt
);
cleanup_fixture_worktree
(
&
fixture
);
}
void
test_worktree_open__open_discovered_worktree
(
void
)
{
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
COMMON_REPO
,
WORKTREE_REPO
);
git_buf
path
=
GIT_BUF_INIT
;
git_repository
*
repo
;
setup_fixture_worktree
(
&
fixture
);
cl_git_pass
(
git_repository_discover
(
&
path
,
git_repository_workdir
(
fixture
.
worktree
),
false
,
NULL
));
cl_git_pass
(
git_repository_open
(
&
repo
,
path
.
ptr
));
...
...
@@ -113,13 +99,14 @@ void test_worktree_open__open_discovered_worktree(void)
git_buf_free
(
&
path
);
git_repository_free
(
repo
);
cleanup_fixture_worktree
(
&
fixture
);
}
void
test_worktree_open__repository_with_nonexistent_parent
(
void
)
{
git_repository
*
repo
;
cleanup_fixture_worktree
(
&
fixture
);
cl_fixture_sandbox
(
WORKTREE_REPO
);
cl_git_pass
(
p_chdir
(
WORKTREE_REPO
));
cl_git_pass
(
cl_rename
(
".gitted"
,
".git"
));
...
...
@@ -130,65 +117,27 @@ void test_worktree_open__repository_with_nonexistent_parent(void)
cl_fixture_cleanup
(
WORKTREE_REPO
);
}
void
test_worktree_open__
submodule_worktree_parent
(
void
)
void
test_worktree_open__
open_from_repository
(
void
)
{
worktree_fixture
fixture
=
WORKTREE_FIXTURE_INIT
(
"submodules"
,
WORKTREE_PARENT
);
setup_fixture_worktree
(
&
fixture
);
git_worktree
*
opened
,
*
lookedup
;
cl_
assert
(
git_repository_path
(
fixture
.
worktree
)
!=
NULL
);
cl_
assert
(
git_repository_workdir
(
fixture
.
worktree
)
!=
NULL
);
cl_
git_pass
(
git_worktree_open_from_repository
(
&
opened
,
fixture
.
worktree
)
);
cl_
git_pass
(
git_worktree_lookup
(
&
lookedup
,
fixture
.
repo
,
WORKTREE_REPO
)
);
cl_assert
(
!
fixture
.
repo
->
is_worktree
);
cl_assert
(
fixture
.
worktree
->
is_worktree
);
cl_assert_equal_s
(
opened
->
name
,
lookedup
->
name
);
cl_assert_equal_s
(
opened
->
gitdir_path
,
lookedup
->
gitdir_path
);
cl_assert_equal_s
(
opened
->
gitlink_path
,
lookedup
->
gitlink_path
);
cl_assert_equal_s
(
opened
->
parent_path
,
lookedup
->
parent_path
);
cl_assert_equal_s
(
opened
->
commondir_path
,
lookedup
->
commondir_path
);
cl_assert_equal_i
(
opened
->
locked
,
lookedup
->
locked
);
cleanup_fixture_worktree
(
&
fixture
);
git_worktree_free
(
opened
);
git_worktree_free
(
lookedup
);
}
void
test_worktree_open__
submodule_worktree_child
(
void
)
void
test_worktree_open__
open_from_nonworktree_fails
(
void
)
{
worktree_fixture
parent_fixture
=
WORKTREE_FIXTURE_INIT
(
"submodules"
,
WORKTREE_PARENT
);
worktree_fixture
child_fixture
=
WORKTREE_FIXTURE_INIT
(
NULL
,
WORKTREE_CHILD
);
setup_fixture_worktree
(
&
parent_fixture
);
cl_git_pass
(
p_rename
(
"submodules/testrepo/.gitted"
,
"submodules/testrepo/.git"
));
setup_fixture_worktree
(
&
child_fixture
);
cl_assert
(
!
parent_fixture
.
repo
->
is_worktree
);
cl_assert
(
parent_fixture
.
worktree
->
is_worktree
);
cl_assert
(
child_fixture
.
worktree
->
is_worktree
);
cleanup_fixture_worktree
(
&
child_fixture
);
cleanup_fixture_worktree
(
&
parent_fixture
);
}
git_worktree
*
wt
;
void
test_worktree_open__open_discovered_submodule_worktree
(
void
)
{
worktree_fixture
parent_fixture
=
WORKTREE_FIXTURE_INIT
(
"submodules"
,
WORKTREE_PARENT
);
worktree_fixture
child_fixture
=
WORKTREE_FIXTURE_INIT
(
NULL
,
WORKTREE_CHILD
);
git_buf
path
=
GIT_BUF_INIT
;
git_repository
*
repo
;
setup_fixture_worktree
(
&
parent_fixture
);
cl_git_pass
(
p_rename
(
"submodules/testrepo/.gitted"
,
"submodules/testrepo/.git"
));
setup_fixture_worktree
(
&
child_fixture
);
cl_git_pass
(
git_repository_discover
(
&
path
,
git_repository_workdir
(
child_fixture
.
worktree
),
false
,
NULL
));
cl_git_pass
(
git_repository_open
(
&
repo
,
path
.
ptr
));
cl_assert_equal_s
(
git_repository_workdir
(
child_fixture
.
worktree
),
git_repository_workdir
(
repo
));
git_buf_free
(
&
path
);
git_repository_free
(
repo
);
cleanup_fixture_worktree
(
&
child_fixture
);
cleanup_fixture_worktree
(
&
parent_fixture
);
cl_git_fail
(
git_worktree_open_from_repository
(
&
wt
,
fixture
.
repo
));
}
tests/worktree/refs.c
View file @
f623cf89
#include "clar_libgit2.h"
#include "path.h"
#include "refs.h"
#include "worktree.h"
#include "worktree_helpers.h"
...
...
@@ -128,3 +130,27 @@ void test_worktree_refs__delete_succeeds_after_pruning_worktree(void)
cl_git_pass
(
git_branch_delete
(
branch
));
git_reference_free
(
branch
);
}
void
test_worktree_refs__creating_refs_uses_commondir
(
void
)
{
git_reference
*
head
,
*
branch
,
*
lookup
;
git_commit
*
commit
;
git_buf
refpath
=
GIT_BUF_INIT
;
cl_git_pass
(
git_buf_joinpath
(
&
refpath
,
git_repository_commondir
(
fixture
.
worktree
),
"refs/heads/testbranch"
));
cl_assert
(
!
git_path_exists
(
refpath
.
ptr
));
cl_git_pass
(
git_repository_head
(
&
head
,
fixture
.
worktree
));
cl_git_pass
(
git_commit_lookup
(
&
commit
,
fixture
.
worktree
,
git_reference_target
(
head
)));
cl_git_pass
(
git_branch_create
(
&
branch
,
fixture
.
worktree
,
"testbranch"
,
commit
,
0
));
cl_git_pass
(
git_branch_lookup
(
&
lookup
,
fixture
.
worktree
,
"testbranch"
,
GIT_BRANCH_LOCAL
));
cl_assert
(
git_reference_cmp
(
branch
,
lookup
)
==
0
);
cl_assert
(
git_path_exists
(
refpath
.
ptr
));
git_reference_free
(
lookup
);
git_reference_free
(
branch
);
git_reference_free
(
head
);
git_commit_free
(
commit
);
git_buf_free
(
&
refpath
);
}
tests/worktree/submodule.c
0 → 100644
View file @
f623cf89
#include "clar_libgit2.h"
#include "repository.h"
#include "worktree.h"
#include "worktree_helpers.h"
#define WORKTREE_PARENT "submodules-worktree-parent"
#define WORKTREE_CHILD "submodules-worktree-child"
static
worktree_fixture
parent
=
WORKTREE_FIXTURE_INIT
(
"submodules"
,
WORKTREE_PARENT
);
static
worktree_fixture
child
=
WORKTREE_FIXTURE_INIT
(
NULL
,
WORKTREE_CHILD
);
void
test_worktree_submodule__initialize
(
void
)
{
setup_fixture_worktree
(
&
parent
);
cl_git_pass
(
p_rename
(
"submodules/testrepo/.gitted"
,
"submodules/testrepo/.git"
));
setup_fixture_worktree
(
&
child
);
}
void
test_worktree_submodule__cleanup
(
void
)
{
cleanup_fixture_worktree
(
&
child
);
cleanup_fixture_worktree
(
&
parent
);
}
void
test_worktree_submodule__submodule_worktree_parent
(
void
)
{
cl_assert
(
git_repository_path
(
parent
.
worktree
)
!=
NULL
);
cl_assert
(
git_repository_workdir
(
parent
.
worktree
)
!=
NULL
);
cl_assert
(
!
parent
.
repo
->
is_worktree
);
cl_assert
(
parent
.
worktree
->
is_worktree
);
}
void
test_worktree_submodule__submodule_worktree_child
(
void
)
{
cl_assert
(
!
parent
.
repo
->
is_worktree
);
cl_assert
(
parent
.
worktree
->
is_worktree
);
cl_assert
(
child
.
worktree
->
is_worktree
);
}
void
test_worktree_submodule__open_discovered_submodule_worktree
(
void
)
{
git_buf
path
=
GIT_BUF_INIT
;
git_repository
*
repo
;
cl_git_pass
(
git_repository_discover
(
&
path
,
git_repository_workdir
(
child
.
worktree
),
false
,
NULL
));
cl_git_pass
(
git_repository_open
(
&
repo
,
path
.
ptr
));
cl_assert_equal_s
(
git_repository_workdir
(
child
.
worktree
),
git_repository_workdir
(
repo
));
git_buf_free
(
&
path
);
git_repository_free
(
repo
);
}
void
test_worktree_submodule__resolve_relative_url
(
void
)
{
git_buf
wt_path
=
GIT_BUF_INIT
;
git_buf
sm_relative_path
=
GIT_BUF_INIT
,
wt_relative_path
=
GIT_BUF_INIT
;
git_repository
*
repo
;
git_worktree
*
wt
;
cl_git_pass
(
git_futils_mkdir
(
"subdir"
,
0755
,
GIT_MKDIR_PATH
));
cl_git_pass
(
git_path_prettify_dir
(
&
wt_path
,
"subdir"
,
NULL
));
cl_git_pass
(
git_buf_joinpath
(
&
wt_path
,
wt_path
.
ptr
,
"wt"
));
/* Open child repository, which is a submodule */
cl_git_pass
(
git_repository_open
(
&
child
.
repo
,
WORKTREE_CHILD
));
/* Create worktree of submodule repository */
cl_git_pass
(
git_worktree_add
(
&
wt
,
child
.
repo
,
"subdir"
,
wt_path
.
ptr
));
cl_git_pass
(
git_repository_open_from_worktree
(
&
repo
,
wt
));
cl_git_pass
(
git_submodule_resolve_url
(
&
sm_relative_path
,
repo
,
"../"
WORKTREE_CHILD
));
cl_git_pass
(
git_submodule_resolve_url
(
&
wt_relative_path
,
child
.
repo
,
"../"
WORKTREE_CHILD
));
cl_assert_equal_s
(
sm_relative_path
.
ptr
,
wt_relative_path
.
ptr
);
git_worktree_free
(
wt
);
git_repository_free
(
repo
);
git_buf_free
(
&
wt_path
);
git_buf_free
(
&
sm_relative_path
);
git_buf_free
(
&
wt_relative_path
);
}
tests/worktree/worktree.c
View file @
f623cf89
...
...
@@ -115,11 +115,12 @@ void test_worktree_worktree__lookup(void)
cl_git_pass
(
git_worktree_lookup
(
&
wt
,
fixture
.
repo
,
"testrepo-worktree"
));
git_buf_printf
(
&
gitdir_path
,
"%s/worktrees/%s"
,
fixture
.
repo
->
commondir
,
"testrepo-worktree"
);
cl_git_pass
(
git_buf_joinpath
(
&
gitdir_path
,
fixture
.
repo
->
commondir
,
"worktrees/testrepo-worktree/"
)
);
cl_assert_equal_s
(
wt
->
gitdir_path
,
gitdir_path
.
ptr
);
cl_assert_equal_s
(
wt
->
parent_path
,
fixture
.
repo
->
git
dir
);
cl_assert_equal_s
(
wt
->
parent_path
,
fixture
.
repo
->
work
dir
);
cl_assert_equal_s
(
wt
->
gitlink_path
,
fixture
.
worktree
->
gitlink
);
cl_assert_equal_s
(
wt
->
commondir_path
,
fixture
.
repo
->
gitdir
);
cl_assert_equal_s
(
wt
->
commondir_path
,
fixture
.
repo
->
commondir
);
git_buf_free
(
&
gitdir_path
);
...
...
@@ -305,7 +306,9 @@ void test_worktree_worktree__init_submodule(void)
cl_git_pass
(
git_worktree_add
(
&
worktree
,
sm
,
"repo-worktree"
,
path
.
ptr
));
cl_git_pass
(
git_repository_open_from_worktree
(
&
wt
,
worktree
));
cl_git_pass
(
git_path_prettify_dir
(
&
path
,
path
.
ptr
,
NULL
));
cl_assert_equal_s
(
path
.
ptr
,
wt
->
workdir
);
cl_git_pass
(
git_path_prettify_dir
(
&
path
,
sm
->
commondir
,
NULL
));
cl_assert_equal_s
(
sm
->
commondir
,
wt
->
commondir
);
cl_git_pass
(
git_buf_joinpath
(
&
path
,
sm
->
gitdir
,
"worktrees/repo-worktree/"
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment