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
354268ca
Commit
354268ca
authored
Jun 26, 2015
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3259 from ethomson/stash_apply_argh
Stash apply: stage new files even when not updating the index
parents
3c7a4697
b7f5cb8d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
323 additions
and
95 deletions
+323
-95
include/git2/errors.h
+1
-0
src/iterator.c
+88
-0
src/iterator.h
+15
-0
src/merge.c
+30
-86
src/stash.c
+104
-0
tests/stash/apply.c
+85
-9
No files found.
include/git2/errors.h
View file @
354268ca
...
@@ -47,6 +47,7 @@ typedef enum {
...
@@ -47,6 +47,7 @@ typedef enum {
GIT_EPEEL
=
-
19
,
/**< The requested peel operation is not possible */
GIT_EPEEL
=
-
19
,
/**< The requested peel operation is not possible */
GIT_EEOF
=
-
20
,
/**< Unexpected EOF */
GIT_EEOF
=
-
20
,
/**< Unexpected EOF */
GIT_EINVALID
=
-
21
,
/**< Invalid operation or input */
GIT_EINVALID
=
-
21
,
/**< Invalid operation or input */
GIT_EUNCOMMITTED
=
-
22
,
/**< Uncommitted changes in index prevented operation */
GIT_PASSTHROUGH
=
-
30
,
/**< Internal only */
GIT_PASSTHROUGH
=
-
30
,
/**< Internal only */
GIT_ITEROVER
=
-
31
,
/**< Signals end of iteration with iterator */
GIT_ITEROVER
=
-
31
,
/**< Signals end of iteration with iterator */
...
...
src/iterator.c
View file @
354268ca
...
@@ -1843,3 +1843,91 @@ int git_iterator_advance_over_with_status(
...
@@ -1843,3 +1843,91 @@ int git_iterator_advance_over_with_status(
return
error
;
return
error
;
}
}
int
git_iterator_walk
(
git_iterator
**
iterators
,
size_t
cnt
,
git_iterator_walk_cb
cb
,
void
*
data
)
{
const
git_index_entry
**
iterator_item
;
/* next in each iterator */
const
git_index_entry
**
cur_items
;
/* current path in each iter */
const
git_index_entry
*
first_match
;
int
cur_item_modified
;
size_t
i
,
j
;
int
error
=
0
;
iterator_item
=
git__calloc
(
cnt
,
sizeof
(
git_index_entry
*
));
cur_items
=
git__calloc
(
cnt
,
sizeof
(
git_index_entry
*
));
GITERR_CHECK_ALLOC
(
iterator_item
);
GITERR_CHECK_ALLOC
(
cur_items
);
/* Set up the iterators */
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
error
=
git_iterator_current
(
&
iterator_item
[
i
],
iterators
[
i
]);
if
(
error
<
0
&&
error
!=
GIT_ITEROVER
)
goto
done
;
}
while
(
true
)
{
for
(
i
=
0
;
i
<
cnt
;
i
++
)
cur_items
[
i
]
=
NULL
;
first_match
=
NULL
;
cur_item_modified
=
0
;
/* Find the next path(s) to consume from each iterator */
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
iterator_item
[
i
]
==
NULL
)
continue
;
if
(
first_match
==
NULL
)
{
first_match
=
iterator_item
[
i
];
cur_items
[
i
]
=
iterator_item
[
i
];
}
else
{
int
path_diff
=
git_index_entry_cmp
(
iterator_item
[
i
],
first_match
);
if
(
path_diff
<
0
)
{
/* Found an index entry that sorts before the one we're
* looking at. Forget that we've seen the other and
* look at the other iterators for this path.
*/
for
(
j
=
0
;
j
<
i
;
j
++
)
cur_items
[
j
]
=
NULL
;
first_match
=
iterator_item
[
i
];
cur_items
[
i
]
=
iterator_item
[
i
];
}
else
if
(
path_diff
>
0
)
{
/* No entry for the current item, this is modified */
cur_item_modified
=
1
;
}
else
if
(
path_diff
==
0
)
{
cur_items
[
i
]
=
iterator_item
[
i
];
}
}
}
if
(
first_match
==
NULL
)
break
;
if
((
error
=
cb
(
cur_items
,
data
))
!=
0
)
goto
done
;
/* Advance each iterator that participated */
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
cur_items
[
i
]
==
NULL
)
continue
;
error
=
git_iterator_advance
(
&
iterator_item
[
i
],
iterators
[
i
]);
if
(
error
<
0
&&
error
!=
GIT_ITEROVER
)
goto
done
;
}
}
done
:
if
(
error
==
GIT_ITEROVER
)
error
=
0
;
return
error
;
}
src/iterator.h
View file @
354268ca
...
@@ -294,4 +294,19 @@ extern int git_iterator_advance_over_with_status(
...
@@ -294,4 +294,19 @@ extern int git_iterator_advance_over_with_status(
*/
*/
extern
int
git_iterator_index
(
git_index
**
out
,
git_iterator
*
iter
);
extern
int
git_iterator_index
(
git_index
**
out
,
git_iterator
*
iter
);
typedef
int
(
*
git_iterator_walk_cb
)(
const
git_index_entry
**
entries
,
void
*
data
);
/**
* Walk the given iterators in lock-step. The given callback will be
* called for each unique path, with the index entry in each iterator
* (or NULL if the given iterator does not contain that path).
*/
extern
int
git_iterator_walk
(
git_iterator
**
iterators
,
size_t
cnt
,
git_iterator_walk_cb
cb
,
void
*
data
);
#endif
#endif
src/merge.c
View file @
354268ca
...
@@ -1449,6 +1449,34 @@ static int merge_diff_list_insert_unmodified(
...
@@ -1449,6 +1449,34 @@ static int merge_diff_list_insert_unmodified(
return
error
;
return
error
;
}
}
struct
merge_diff_find_data
{
git_merge_diff_list
*
diff_list
;
struct
merge_diff_df_data
df_data
;
};
static
int
queue_difference
(
const
git_index_entry
**
entries
,
void
*
data
)
{
struct
merge_diff_find_data
*
find_data
=
data
;
bool
item_modified
=
false
;
size_t
i
;
if
(
!
entries
[
0
]
||
!
entries
[
1
]
||
!
entries
[
2
])
{
item_modified
=
true
;
}
else
{
for
(
i
=
1
;
i
<
3
;
i
++
)
{
if
(
index_entry_cmp
(
entries
[
0
],
entries
[
i
])
!=
0
)
{
item_modified
=
true
;
break
;
}
}
}
return
item_modified
?
merge_diff_list_insert_conflict
(
find_data
->
diff_list
,
&
find_data
->
df_data
,
entries
)
:
merge_diff_list_insert_unmodified
(
find_data
->
diff_list
,
entries
);
}
int
git_merge_diff_list__find_differences
(
int
git_merge_diff_list__find_differences
(
git_merge_diff_list
*
diff_list
,
git_merge_diff_list
*
diff_list
,
git_iterator
*
ancestor_iter
,
git_iterator
*
ancestor_iter
,
...
@@ -1456,93 +1484,9 @@ int git_merge_diff_list__find_differences(
...
@@ -1456,93 +1484,9 @@ int git_merge_diff_list__find_differences(
git_iterator
*
their_iter
)
git_iterator
*
their_iter
)
{
{
git_iterator
*
iterators
[
3
]
=
{
ancestor_iter
,
our_iter
,
their_iter
};
git_iterator
*
iterators
[
3
]
=
{
ancestor_iter
,
our_iter
,
their_iter
};
const
git_index_entry
*
items
[
3
]
=
{
0
},
*
best_cur_item
,
*
cur_items
[
3
];
struct
merge_diff_find_data
find_data
=
{
diff_list
};
git_vector_cmp
entry_compare
=
git_index_entry_cmp
;
struct
merge_diff_df_data
df_data
=
{
0
};
int
cur_item_modified
;
size_t
i
,
j
;
int
error
=
0
;
assert
(
diff_list
&&
(
our_iter
||
their_iter
));
/* Set up the iterators */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
error
=
git_iterator_current
(
&
items
[
i
],
iterators
[
i
]);
if
(
error
<
0
&&
error
!=
GIT_ITEROVER
)
goto
done
;
}
while
(
true
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
cur_items
[
i
]
=
NULL
;
best_cur_item
=
NULL
;
cur_item_modified
=
0
;
/* Find the next path(s) to consume from each iterator */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
items
[
i
]
==
NULL
)
{
cur_item_modified
=
1
;
continue
;
}
if
(
best_cur_item
==
NULL
)
{
best_cur_item
=
items
[
i
];
cur_items
[
i
]
=
items
[
i
];
}
else
{
int
path_diff
=
entry_compare
(
items
[
i
],
best_cur_item
);
if
(
path_diff
<
0
)
{
/*
* Found an item that sorts before our current item, make
* our current item this one.
*/
for
(
j
=
0
;
j
<
i
;
j
++
)
cur_items
[
j
]
=
NULL
;
cur_item_modified
=
1
;
best_cur_item
=
items
[
i
];
cur_items
[
i
]
=
items
[
i
];
}
else
if
(
path_diff
>
0
)
{
/* No entry for the current item, this is modified */
cur_item_modified
=
1
;
}
else
if
(
path_diff
==
0
)
{
cur_items
[
i
]
=
items
[
i
];
if
(
!
cur_item_modified
)
cur_item_modified
=
index_entry_cmp
(
best_cur_item
,
items
[
i
]);
}
}
}
if
(
best_cur_item
==
NULL
)
break
;
if
(
cur_item_modified
)
error
=
merge_diff_list_insert_conflict
(
diff_list
,
&
df_data
,
cur_items
);
else
error
=
merge_diff_list_insert_unmodified
(
diff_list
,
cur_items
);
if
(
error
<
0
)
goto
done
;
/* Advance each iterator that participated */
return
git_iterator_walk
(
iterators
,
3
,
queue_difference
,
&
find_data
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
cur_items
[
i
]
==
NULL
)
continue
;
error
=
git_iterator_advance
(
&
items
[
i
],
iterators
[
i
]);
if
(
error
<
0
&&
error
!=
GIT_ITEROVER
)
goto
done
;
}
}
done
:
if
(
error
==
GIT_ITEROVER
)
error
=
0
;
return
error
;
}
}
git_merge_diff_list
*
git_merge_diff_list__alloc
(
git_repository
*
repo
)
git_merge_diff_list
*
git_merge_diff_list__alloc
(
git_repository
*
repo
)
...
...
src/stash.c
View file @
354268ca
...
@@ -671,6 +671,31 @@ cleanup:
...
@@ -671,6 +671,31 @@ cleanup:
return
error
;
return
error
;
}
}
static
int
merge_indexes
(
git_index
**
out
,
git_repository
*
repo
,
git_tree
*
ancestor_tree
,
git_index
*
ours_index
,
git_index
*
theirs_index
)
{
git_iterator
*
ancestor
=
NULL
,
*
ours
=
NULL
,
*
theirs
=
NULL
;
const
git_iterator_flag_t
flags
=
GIT_ITERATOR_DONT_IGNORE_CASE
;
int
error
;
if
((
error
=
git_iterator_for_tree
(
&
ancestor
,
ancestor_tree
,
flags
,
NULL
,
NULL
))
<
0
||
(
error
=
git_iterator_for_index
(
&
ours
,
ours_index
,
flags
,
NULL
,
NULL
))
<
0
||
(
error
=
git_iterator_for_index
(
&
theirs
,
theirs_index
,
flags
,
NULL
,
NULL
))
<
0
)
goto
done
;
error
=
git_merge__iterators
(
out
,
repo
,
ancestor
,
ours
,
theirs
,
NULL
);
done:
git_iterator_free
(
ancestor
);
git_iterator_free
(
ours
);
git_iterator_free
(
theirs
);
return
error
;
}
static
int
merge_index_and_tree
(
static
int
merge_index_and_tree
(
git_index
**
out
,
git_index
**
out
,
git_repository
*
repo
,
git_repository
*
repo
,
...
@@ -733,6 +758,70 @@ int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int ver
...
@@ -733,6 +758,70 @@ int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int ver
} \
} \
} while(false);
} while(false);
static
int
ensure_clean_index
(
git_repository
*
repo
,
git_index
*
index
)
{
git_tree
*
head_tree
=
NULL
;
git_diff
*
index_diff
=
NULL
;
int
error
=
0
;
if
((
error
=
git_repository_head_tree
(
&
head_tree
,
repo
))
<
0
||
(
error
=
git_diff_tree_to_index
(
&
index_diff
,
repo
,
head_tree
,
index
,
NULL
))
<
0
)
goto
done
;
if
(
git_diff_num_deltas
(
index_diff
)
>
0
)
{
giterr_set
(
GITERR_STASH
,
"%d uncommitted changes exist in the index"
,
git_diff_num_deltas
(
index_diff
));
error
=
GIT_EUNCOMMITTED
;
}
done:
git_diff_free
(
index_diff
);
git_tree_free
(
head_tree
);
return
error
;
}
static
int
stage_new_file
(
const
git_index_entry
**
entries
,
void
*
data
)
{
git_index
*
index
=
data
;
if
(
entries
[
0
]
==
NULL
)
return
git_index_add
(
index
,
entries
[
1
]);
else
return
git_index_add
(
index
,
entries
[
0
]);
}
static
int
stage_new_files
(
git_index
**
out
,
git_repository
*
repo
,
git_tree
*
parent_tree
,
git_tree
*
tree
)
{
git_iterator
*
iterators
[
2
]
=
{
NULL
,
NULL
};
git_index
*
index
=
NULL
;
int
error
;
if
((
error
=
git_index_new
(
&
index
))
<
0
||
(
error
=
git_iterator_for_tree
(
&
iterators
[
0
],
parent_tree
,
GIT_ITERATOR_DONT_IGNORE_CASE
,
NULL
,
NULL
))
<
0
||
(
error
=
git_iterator_for_tree
(
&
iterators
[
1
],
tree
,
GIT_ITERATOR_DONT_IGNORE_CASE
,
NULL
,
NULL
))
<
0
)
goto
done
;
error
=
git_iterator_walk
(
iterators
,
2
,
stage_new_file
,
index
);
done:
if
(
error
<
0
)
git_index_free
(
index
);
else
*
out
=
index
;
git_iterator_free
(
iterators
[
0
]);
git_iterator_free
(
iterators
[
1
]);
return
error
;
}
int
git_stash_apply
(
int
git_stash_apply
(
git_repository
*
repo
,
git_repository
*
repo
,
size_t
index
,
size_t
index
,
...
@@ -746,6 +835,7 @@ int git_stash_apply(
...
@@ -746,6 +835,7 @@ int git_stash_apply(
git_tree
*
index_tree
=
NULL
;
git_tree
*
index_tree
=
NULL
;
git_tree
*
index_parent_tree
=
NULL
;
git_tree
*
index_parent_tree
=
NULL
;
git_tree
*
untracked_tree
=
NULL
;
git_tree
*
untracked_tree
=
NULL
;
git_index
*
stash_adds
=
NULL
;
git_index
*
repo_index
=
NULL
;
git_index
*
repo_index
=
NULL
;
git_index
*
unstashed_index
=
NULL
;
git_index
*
unstashed_index
=
NULL
;
git_index
*
modified_index
=
NULL
;
git_index
*
modified_index
=
NULL
;
...
@@ -775,6 +865,9 @@ int git_stash_apply(
...
@@ -775,6 +865,9 @@ int git_stash_apply(
NOTIFY_PROGRESS
(
opts
,
GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX
);
NOTIFY_PROGRESS
(
opts
,
GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX
);
if
((
error
=
ensure_clean_index
(
repo
,
repo_index
))
<
0
)
goto
cleanup
;
/* Restore index if required */
/* Restore index if required */
if
((
opts
.
flags
&
GIT_STASH_APPLY_REINSTATE_INDEX
)
&&
if
((
opts
.
flags
&
GIT_STASH_APPLY_REINSTATE_INDEX
)
&&
git_oid_cmp
(
git_tree_id
(
stash_parent_tree
),
git_tree_id
(
index_tree
)))
{
git_oid_cmp
(
git_tree_id
(
stash_parent_tree
),
git_tree_id
(
index_tree
)))
{
...
@@ -787,6 +880,16 @@ int git_stash_apply(
...
@@ -787,6 +880,16 @@ int git_stash_apply(
error
=
GIT_ECONFLICT
;
error
=
GIT_ECONFLICT
;
goto
cleanup
;
goto
cleanup
;
}
}
/* Otherwise, stage any new files in the stash tree. (Note: their
* previously unstaged contents are staged, not the previously staged.)
*/
}
else
if
((
opts
.
flags
&
GIT_STASH_APPLY_REINSTATE_INDEX
)
==
0
)
{
if
((
error
=
stage_new_files
(
&
stash_adds
,
repo
,
stash_parent_tree
,
stash_tree
))
<
0
||
(
error
=
merge_indexes
(
&
unstashed_index
,
repo
,
stash_parent_tree
,
repo_index
,
stash_adds
))
<
0
)
goto
cleanup
;
}
}
NOTIFY_PROGRESS
(
opts
,
GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED
);
NOTIFY_PROGRESS
(
opts
,
GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED
);
...
@@ -848,6 +951,7 @@ cleanup:
...
@@ -848,6 +951,7 @@ cleanup:
git_index_free
(
untracked_index
);
git_index_free
(
untracked_index
);
git_index_free
(
modified_index
);
git_index_free
(
modified_index
);
git_index_free
(
unstashed_index
);
git_index_free
(
unstashed_index
);
git_index_free
(
stash_adds
);
git_index_free
(
repo_index
);
git_index_free
(
repo_index
);
git_tree_free
(
untracked_tree
);
git_tree_free
(
untracked_tree
);
git_tree_free
(
index_parent_tree
);
git_tree_free
(
index_parent_tree
);
...
...
tests/stash/apply.c
View file @
354268ca
...
@@ -10,14 +10,14 @@ void test_stash_apply__initialize(void)
...
@@ -10,14 +10,14 @@ void test_stash_apply__initialize(void)
{
{
git_oid
oid
;
git_oid
oid
;
cl_git_pass
(
git_signature_new
(
&
signature
,
"nulltoken"
,
"emeric.fermas@gmail.com"
,
1323847743
,
60
));
/* Wed Dec 14 08:29:03 2011 +0100 */
repo
=
cl_git_sandbox_init_new
(
"stash"
);
cl_git_pass
(
git_repository_init
(
&
repo
,
"stash"
,
0
));
cl_git_pass
(
git_repository_index
(
&
repo_index
,
repo
));
cl_git_pass
(
git_repository_index
(
&
repo_index
,
repo
));
cl_git_pass
(
git_signature_new
(
&
signature
,
"nulltoken"
,
"emeric.fermas@gmail.com"
,
1323847743
,
60
));
/* Wed Dec 14 08:29:03 2011 +0100 */
cl_git_mkfile
(
"stash/what"
,
"hello
\n
"
);
cl_git_mkfile
(
"stash/what"
,
"hello
\n
"
);
cl_git_mkfile
(
"stash/how"
,
"small
\n
"
);
cl_git_mkfile
(
"stash/how"
,
"small
\n
"
);
cl_git_mkfile
(
"stash/who"
,
"world
\n
"
);
cl_git_mkfile
(
"stash/who"
,
"world
\n
"
);
cl_git_mkfile
(
"stash/where"
,
"meh
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"what"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"what"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"how"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"how"
));
...
@@ -28,14 +28,23 @@ void test_stash_apply__initialize(void)
...
@@ -28,14 +28,23 @@ void test_stash_apply__initialize(void)
cl_git_rewritefile
(
"stash/what"
,
"goodbye
\n
"
);
cl_git_rewritefile
(
"stash/what"
,
"goodbye
\n
"
);
cl_git_rewritefile
(
"stash/who"
,
"funky world
\n
"
);
cl_git_rewritefile
(
"stash/who"
,
"funky world
\n
"
);
cl_git_mkfile
(
"stash/when"
,
"tomorrow
\n
"
);
cl_git_mkfile
(
"stash/when"
,
"tomorrow
\n
"
);
cl_git_mkfile
(
"stash/why"
,
"would anybody use stash?
\n
"
);
cl_git_mkfile
(
"stash/where"
,
"????
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"why"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"where"
));
git_index_write
(
repo_index
);
cl_git_rewritefile
(
"stash/where"
,
"....
\n
"
);
/* Pre-stash state */
/* Pre-stash state */
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
assert_status
(
repo
,
"where"
,
GIT_STATUS_INDEX_NEW
|
GIT_STATUS_WT_MODIFIED
);
cl_git_pass
(
git_stash_save
(
&
oid
,
repo
,
signature
,
NULL
,
GIT_STASH_INCLUDE_UNTRACKED
));
cl_git_pass
(
git_stash_save
(
&
oid
,
repo
,
signature
,
NULL
,
GIT_STASH_INCLUDE_UNTRACKED
));
...
@@ -44,6 +53,8 @@ void test_stash_apply__initialize(void)
...
@@ -44,6 +53,8 @@ void test_stash_apply__initialize(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_ENOTFOUND
);
assert_status
(
repo
,
"when"
,
GIT_ENOTFOUND
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
assert_status
(
repo
,
"where"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__cleanup
(
void
)
void
test_stash_apply__cleanup
(
void
)
...
@@ -54,15 +65,13 @@ void test_stash_apply__cleanup(void)
...
@@ -54,15 +65,13 @@ void test_stash_apply__cleanup(void)
git_index_free
(
repo_index
);
git_index_free
(
repo_index
);
repo_index
=
NULL
;
repo_index
=
NULL
;
git_repository_free
(
repo
);
cl_git_sandbox_cleanup
();
repo
=
NULL
;
cl_git_pass
(
git_futils_rmdir_r
(
"stash"
,
NULL
,
GIT_RMDIR_REMOVE_FILES
));
cl_fixture_cleanup
(
"sorry-it-is-a-non-bare-only-party"
);
}
}
void
test_stash_apply__with_default
(
void
)
void
test_stash_apply__with_default
(
void
)
{
{
git_buf
where
=
GIT_BUF_INIT
;
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
NULL
));
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
NULL
));
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
...
@@ -70,10 +79,42 @@ void test_stash_apply__with_default(void)
...
@@ -70,10 +79,42 @@ void test_stash_apply__with_default(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
assert_status
(
repo
,
"where"
,
GIT_STATUS_INDEX_NEW
);
cl_git_pass
(
git_futils_readbuffer
(
&
where
,
"stash/where"
));
cl_assert_equal_s
(
"....
\n
"
,
where
.
ptr
);
git_buf_free
(
&
where
);
}
void
test_stash_apply__with_existing_file
(
void
)
{
cl_git_mkfile
(
"stash/where"
,
"oops!
\n
"
);
cl_git_fail
(
git_stash_apply
(
repo
,
0
,
NULL
));
}
void
test_stash_apply__merges_new_file
(
void
)
{
git_index_entry
*
ancestor
,
*
our
,
*
their
;
cl_git_mkfile
(
"stash/where"
,
"committed before stash
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"where"
));
cl_repo_commit_from_index
(
NULL
,
repo
,
signature
,
0
,
"Other commit"
);
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
NULL
));
cl_assert_equal_i
(
1
,
git_index_has_conflicts
(
repo_index
));
assert_status
(
repo
,
"what"
,
GIT_STATUS_INDEX_MODIFIED
);
cl_git_pass
(
git_index_conflict_get
(
&
ancestor
,
&
our
,
&
their
,
repo_index
,
"where"
));
/* unmerged */
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
}
}
void
test_stash_apply__with_reinstate_index
(
void
)
void
test_stash_apply__with_reinstate_index
(
void
)
{
{
git_buf
where
=
GIT_BUF_INIT
;
git_stash_apply_options
opts
=
GIT_STASH_APPLY_OPTIONS_INIT
;
git_stash_apply_options
opts
=
GIT_STASH_APPLY_OPTIONS_INIT
;
opts
.
flags
=
GIT_STASH_APPLY_REINSTATE_INDEX
;
opts
.
flags
=
GIT_STASH_APPLY_REINSTATE_INDEX
;
...
@@ -85,6 +126,13 @@ void test_stash_apply__with_reinstate_index(void)
...
@@ -85,6 +126,13 @@ void test_stash_apply__with_reinstate_index(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
assert_status
(
repo
,
"where"
,
GIT_STATUS_INDEX_NEW
|
GIT_STATUS_WT_MODIFIED
);
cl_git_pass
(
git_futils_readbuffer
(
&
where
,
"stash/where"
));
cl_assert_equal_s
(
"....
\n
"
,
where
.
ptr
);
git_buf_free
(
&
where
);
}
}
void
test_stash_apply__conflict_index_with_default
(
void
)
void
test_stash_apply__conflict_index_with_default
(
void
)
...
@@ -96,6 +144,7 @@ void test_stash_apply__conflict_index_with_default(void)
...
@@ -96,6 +144,7 @@ void test_stash_apply__conflict_index_with_default(void)
cl_git_rewritefile
(
"stash/who"
,
"nothing
\n
"
);
cl_git_rewritefile
(
"stash/who"
,
"nothing
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_write
(
repo_index
));
cl_git_pass
(
git_index_write
(
repo_index
));
cl_repo_commit_from_index
(
NULL
,
repo
,
signature
,
0
,
"Other commit"
);
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
NULL
));
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
NULL
));
...
@@ -104,6 +153,7 @@ void test_stash_apply__conflict_index_with_default(void)
...
@@ -104,6 +153,7 @@ void test_stash_apply__conflict_index_with_default(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
cl_git_pass
(
git_index_conflict_get
(
&
ancestor
,
&
our
,
&
their
,
repo_index
,
"who"
));
/* unmerged */
cl_git_pass
(
git_index_conflict_get
(
&
ancestor
,
&
our
,
&
their
,
repo_index
,
"who"
));
/* unmerged */
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
}
}
void
test_stash_apply__conflict_index_with_reinstate_index
(
void
)
void
test_stash_apply__conflict_index_with_reinstate_index
(
void
)
...
@@ -115,14 +165,16 @@ void test_stash_apply__conflict_index_with_reinstate_index(void)
...
@@ -115,14 +165,16 @@ void test_stash_apply__conflict_index_with_reinstate_index(void)
cl_git_rewritefile
(
"stash/who"
,
"nothing
\n
"
);
cl_git_rewritefile
(
"stash/who"
,
"nothing
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_write
(
repo_index
));
cl_git_pass
(
git_index_write
(
repo_index
));
cl_repo_commit_from_index
(
NULL
,
repo
,
signature
,
0
,
"Other commit"
);
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
&
opts
),
GIT_ECONFLICT
);
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
&
opts
),
GIT_ECONFLICT
);
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_
INDEX_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_
CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_ENOTFOUND
);
assert_status
(
repo
,
"when"
,
GIT_ENOTFOUND
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__conflict_untracked_with_default
(
void
)
void
test_stash_apply__conflict_untracked_with_default
(
void
)
...
@@ -138,6 +190,7 @@ void test_stash_apply__conflict_untracked_with_default(void)
...
@@ -138,6 +190,7 @@ void test_stash_apply__conflict_untracked_with_default(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__conflict_untracked_with_reinstate_index
(
void
)
void
test_stash_apply__conflict_untracked_with_reinstate_index
(
void
)
...
@@ -155,6 +208,7 @@ void test_stash_apply__conflict_untracked_with_reinstate_index(void)
...
@@ -155,6 +208,7 @@ void test_stash_apply__conflict_untracked_with_reinstate_index(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__conflict_workdir_with_default
(
void
)
void
test_stash_apply__conflict_workdir_with_default
(
void
)
...
@@ -168,6 +222,7 @@ void test_stash_apply__conflict_workdir_with_default(void)
...
@@ -168,6 +222,7 @@ void test_stash_apply__conflict_workdir_with_default(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__conflict_workdir_with_reinstate_index
(
void
)
void
test_stash_apply__conflict_workdir_with_reinstate_index
(
void
)
...
@@ -185,6 +240,7 @@ void test_stash_apply__conflict_workdir_with_reinstate_index(void)
...
@@ -185,6 +240,7 @@ void test_stash_apply__conflict_workdir_with_reinstate_index(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__conflict_commit_with_default
(
void
)
void
test_stash_apply__conflict_commit_with_default
(
void
)
...
@@ -204,6 +260,7 @@ void test_stash_apply__conflict_commit_with_default(void)
...
@@ -204,6 +260,7 @@ void test_stash_apply__conflict_commit_with_default(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
}
}
void
test_stash_apply__conflict_commit_with_reinstate_index
(
void
)
void
test_stash_apply__conflict_commit_with_reinstate_index
(
void
)
...
@@ -226,6 +283,23 @@ void test_stash_apply__conflict_commit_with_reinstate_index(void)
...
@@ -226,6 +283,23 @@ void test_stash_apply__conflict_commit_with_reinstate_index(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
}
void
test_stash_apply__fails_with_uncommitted_changes_in_index
(
void
)
{
cl_git_rewritefile
(
"stash/who"
,
"nothing
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
cl_git_pass
(
git_index_write
(
repo_index
));
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
NULL
),
GIT_EUNCOMMITTED
);
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_ENOTFOUND
);
assert_status
(
repo
,
"why"
,
GIT_ENOTFOUND
);
}
}
void
test_stash_apply__pop
(
void
)
void
test_stash_apply__pop
(
void
)
...
@@ -285,6 +359,8 @@ void test_stash_apply__executes_notify_cb(void)
...
@@ -285,6 +359,8 @@ void test_stash_apply__executes_notify_cb(void)
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
assert_status
(
repo
,
"why"
,
GIT_STATUS_INDEX_NEW
);
assert_status
(
repo
,
"where"
,
GIT_STATUS_INDEX_NEW
);
cl_assert_equal_b
(
true
,
seen_paths
.
what
);
cl_assert_equal_b
(
true
,
seen_paths
.
what
);
cl_assert_equal_b
(
false
,
seen_paths
.
how
);
cl_assert_equal_b
(
false
,
seen_paths
.
how
);
...
...
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