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
bf8dd3f5
Commit
bf8dd3f5
authored
Nov 14, 2014
by
Pierre-Olivier Latour
Committed by
Edward Thomson
May 11, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added git_stash_apply() and git_stash_pop() APIs
parent
9cdd6578
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
280 additions
and
4 deletions
+280
-4
AUTHORS
+1
-0
include/git2/stash.h
+64
-4
src/stash.c
+0
-0
tests/stash/apply.c
+215
-0
No files found.
AUTHORS
View file @
bf8dd3f5
...
@@ -49,6 +49,7 @@ Microsoft Corporation
...
@@ -49,6 +49,7 @@ Microsoft Corporation
Olivier Ramonat
Olivier Ramonat
Peter Drahoš
Peter Drahoš
Pierre Habouzit
Pierre Habouzit
Pierre-Olivier Latour
Przemyslaw Pawelczyk
Przemyslaw Pawelczyk
Ramsay Jones
Ramsay Jones
Robert G. Jakabosky
Robert G. Jakabosky
...
...
include/git2/stash.h
View file @
bf8dd3f5
...
@@ -70,6 +70,47 @@ GIT_EXTERN(int) git_stash_save(
...
@@ -70,6 +70,47 @@ GIT_EXTERN(int) git_stash_save(
const
char
*
message
,
const
char
*
message
,
unsigned
int
flags
);
unsigned
int
flags
);
typedef
enum
{
GIT_APPLY_DEFAULT
=
0
,
/* Try to reinstate not only the working tree's changes,
* but also the index's ones.
*/
GIT_APPLY_REINSTATE_INDEX
=
(
1
<<
0
),
}
git_apply_flags
;
/**
* Apply a single stashed state from the stash list.
*
* If any untracked or ignored file saved in the stash already exist in the
* workdir, the function will return GIT_EEXISTS and both the workdir and index
* will be left untouched.
*
* If local changes in the workdir would be overwritten when applying
* modifications saved in the stash, the function will return GIT_EMERGECONFLICT
* and the index will be left untouched. The workdir files will be left
* unmodified as well but restored untracked or ignored files that were saved
* in the stash will be left around in the workdir.
*
* If passing the GIT_APPLY_REINSTATE_INDEX flag and there would be conflicts
* when reinstating the index, the function will return GIT_EUNMERGED and both
* the workdir and index will be left untouched.
*
* @param repo The owning repository.
*
* @param index The position within the stash list. 0 points to the
* most recent stashed state.
*
* @param flags Flags to control the applying process. (see GIT_APPLY_* above)
*
* @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
* index, or error code. (see details above)
*/
GIT_EXTERN
(
int
)
git_stash_apply
(
git_repository
*
repo
,
size_t
index
,
unsigned
int
flags
);
/**
/**
* This is a callback function you can provide to iterate over all the
* This is a callback function you can provide to iterate over all the
* stashed states that will be invoked per entry.
* stashed states that will be invoked per entry.
...
@@ -79,7 +120,7 @@ GIT_EXTERN(int) git_stash_save(
...
@@ -79,7 +120,7 @@ GIT_EXTERN(int) git_stash_save(
* @param message The stash message.
* @param message The stash message.
* @param stash_id The commit oid of the stashed state.
* @param stash_id The commit oid of the stashed state.
* @param payload Extra parameter to callback function.
* @param payload Extra parameter to callback function.
* @return 0 to continue iterating or non-zero to stop
* @return 0 to continue iterating or non-zero to stop
.
*/
*/
typedef
int
(
*
git_stash_cb
)(
typedef
int
(
*
git_stash_cb
)(
size_t
index
,
size_t
index
,
...
@@ -99,7 +140,7 @@ typedef int (*git_stash_cb)(
...
@@ -99,7 +140,7 @@ typedef int (*git_stash_cb)(
*
*
* @param payload Extra parameter to callback function.
* @param payload Extra parameter to callback function.
*
*
* @return 0 on success, non-zero callback return value, or error code
* @return 0 on success, non-zero callback return value, or error code
.
*/
*/
GIT_EXTERN
(
int
)
git_stash_foreach
(
GIT_EXTERN
(
int
)
git_stash_foreach
(
git_repository
*
repo
,
git_repository
*
repo
,
...
@@ -114,13 +155,32 @@ GIT_EXTERN(int) git_stash_foreach(
...
@@ -114,13 +155,32 @@ GIT_EXTERN(int) git_stash_foreach(
* @param index The position within the stash list. 0 points to the
* @param index The position within the stash list. 0 points to the
* most recent stashed state.
* most recent stashed state.
*
*
* @return 0 on success, or error code
* @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
* index, or error code.
*/
*/
GIT_EXTERN
(
int
)
git_stash_drop
(
GIT_EXTERN
(
int
)
git_stash_drop
(
git_repository
*
repo
,
git_repository
*
repo
,
size_t
index
);
size_t
index
);
/**
* Apply a single stashed state from the stash list and remove it from the list
* if successful.
*
* @param repo The owning repository.
*
* @param index The position within the stash list. 0 points to the
* most recent stashed state.
*
* @param flags Flags to control the applying process. (see GIT_APPLY_* above)
*
* @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
* index, or error code. (see git_stash_apply() above for details)
*/
GIT_EXTERN
(
int
)
git_stash_pop
(
git_repository
*
repo
,
size_t
index
,
unsigned
int
flags
);
/** @} */
/** @} */
GIT_END_DECL
GIT_END_DECL
#endif
#endif
src/stash.c
View file @
bf8dd3f5
This diff is collapsed.
Click to expand it.
tests/stash/apply.c
0 → 100644
View file @
bf8dd3f5
#include "clar_libgit2.h"
#include "fileops.h"
#include "stash_helpers.h"
static
git_signature
*
signature
;
static
git_repository
*
repo
;
static
git_index
*
repo_index
;
void
test_stash_apply__initialize
(
void
)
{
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 */
cl_git_pass
(
git_repository_init
(
&
repo
,
"stash"
,
0
));
cl_git_pass
(
git_repository_index
(
&
repo_index
,
repo
));
cl_git_mkfile
(
"stash/what"
,
"hello
\n
"
);
cl_git_mkfile
(
"stash/how"
,
"small
\n
"
);
cl_git_mkfile
(
"stash/who"
,
"world
\n
"
);
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
,
"who"
));
cl_repo_commit_from_index
(
NULL
,
repo
,
signature
,
0
,
"Initial commit"
);
cl_git_rewritefile
(
"stash/what"
,
"goodbye
\n
"
);
cl_git_rewritefile
(
"stash/who"
,
"funky world
\n
"
);
cl_git_mkfile
(
"stash/when"
,
"tomorrow
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"who"
));
/* Pre-stash state */
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
cl_git_pass
(
git_stash_save
(
&
oid
,
repo
,
signature
,
NULL
,
GIT_STASH_INCLUDE_UNTRACKED
));
/* Post-stash state */
assert_status
(
repo
,
"what"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_ENOTFOUND
);
}
void
test_stash_apply__cleanup
(
void
)
{
git_signature_free
(
signature
);
signature
=
NULL
;
git_index_free
(
repo_index
);
repo_index
=
NULL
;
git_repository_free
(
repo
);
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
)
{
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_DEFAULT
));
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__with_reinstate_index
(
void
)
{
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_REINSTATE_INDEX
));
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_index_with_default
(
void
)
{
const
git_index_entry
*
ancestor
;
const
git_index_entry
*
our
;
const
git_index_entry
*
their
;
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_pass
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_DEFAULT
));
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
1
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
cl_git_pass
(
git_index_conflict_get
(
&
ancestor
,
&
our
,
&
their
,
repo_index
,
"who"
));
/* unmerged */
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_index_with_reinstate_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
,
GIT_APPLY_REINSTATE_INDEX
),
GIT_EUNMERGED
);
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
);
}
void
test_stash_apply__conflict_untracked_with_default
(
void
)
{
cl_git_mkfile
(
"stash/when"
,
"nothing
\n
"
);
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_DEFAULT
),
GIT_EEXISTS
);
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_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_untracked_with_reinstate_index
(
void
)
{
cl_git_mkfile
(
"stash/when"
,
"nothing
\n
"
);
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_REINSTATE_INDEX
),
GIT_EEXISTS
);
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_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_workdir_with_default
(
void
)
{
cl_git_rewritefile
(
"stash/what"
,
"ciao
\n
"
);
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_DEFAULT
),
GIT_EMERGECONFLICT
);
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_workdir_with_reinstate_index
(
void
)
{
cl_git_rewritefile
(
"stash/what"
,
"ciao
\n
"
);
cl_git_fail_with
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_REINSTATE_INDEX
),
GIT_EMERGECONFLICT
);
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
0
);
assert_status
(
repo
,
"what"
,
GIT_STATUS_WT_MODIFIED
);
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_commit_with_default
(
void
)
{
const
git_index_entry
*
ancestor
;
const
git_index_entry
*
our
;
const
git_index_entry
*
their
;
cl_git_rewritefile
(
"stash/what"
,
"ciao
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"what"
));
cl_repo_commit_from_index
(
NULL
,
repo
,
signature
,
0
,
"Other commit"
);
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_DEFAULT
));
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
1
);
cl_git_pass
(
git_index_conflict_get
(
&
ancestor
,
&
our
,
&
their
,
repo_index
,
"what"
));
/* unmerged */
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__conflict_commit_with_reinstate_index
(
void
)
{
const
git_index_entry
*
ancestor
;
const
git_index_entry
*
our
;
const
git_index_entry
*
their
;
cl_git_rewritefile
(
"stash/what"
,
"ciao
\n
"
);
cl_git_pass
(
git_index_add_bypath
(
repo_index
,
"what"
));
cl_repo_commit_from_index
(
NULL
,
repo
,
signature
,
0
,
"Other commit"
);
cl_git_pass
(
git_stash_apply
(
repo
,
0
,
GIT_APPLY_REINSTATE_INDEX
));
cl_assert_equal_i
(
git_index_has_conflicts
(
repo_index
),
1
);
cl_git_pass
(
git_index_conflict_get
(
&
ancestor
,
&
our
,
&
their
,
repo_index
,
"what"
));
/* unmerged */
assert_status
(
repo
,
"how"
,
GIT_STATUS_CURRENT
);
assert_status
(
repo
,
"who"
,
GIT_STATUS_INDEX_MODIFIED
);
assert_status
(
repo
,
"when"
,
GIT_STATUS_WT_NEW
);
}
void
test_stash_apply__pop
(
void
)
{
cl_git_pass
(
git_stash_pop
(
repo
,
0
,
GIT_APPLY_DEFAULT
));
cl_git_fail_with
(
git_stash_pop
(
repo
,
0
,
GIT_APPLY_DEFAULT
),
GIT_ENOTFOUND
);
}
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