Skip to content

Commit

Permalink
[44_7] Version: impl git-status-file
Browse files Browse the repository at this point in the history
  • Loading branch information
da-liii authored Jan 15, 2024
1 parent 88850ef commit bd00a30
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 8 deletions.
106 changes: 106 additions & 0 deletions TeXmacs/tests/44_7.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

(define (test-unmodified)
(if (== (git-status-file "LICENSE" (url-pwd)) " ")
1
(error "short status of LICENSE should be ' ' but not" st)))

(define (test-git-deleted)
(system "git rm LICENSE")
(with st (git-status-file "LICENSE" (url-pwd))
(system "git reset HEAD LICENSE")
(system "git checkout LICENSE")
(if (== st "D ")
1
(error "short status of LICENSE should be 'D ' but not " st))))

(define (test-file-deleted)
(system-remove "LICENSE")
(with st (git-status-file "LICENSE" (url-pwd))
(system "git checkout LICENSE")
(if (== st " D")
1
(error "short status of LICENSE should be ' D' but not " st))))

(define (test-file-ignored)
(system-copy "LICENSE" "LICENSE.log")
(with st (git-status-file "LICENSE.log" (url-pwd))
(system-remove "LICENSE.log")
(if (== st "!!")
1
(error "short status of LICENSE should be '!!' but not " st))))

(define (test-git-added)
(system-copy "LICENSE" "LICENSE.add")
(system "git add LICENSE.add")
(with st (git-status-file "LICENSE.add" (url-pwd))
(system "git rm -f LICENSE.add")
(if (== st "A ")
1
(error "short status of LICENSE should be 'A ' but not " st))))

(define (test-file-added)
(system-copy "LICENSE" "LICENSE.add")
(with st (git-status-file "LICENSE.add" (url-pwd))
(system-remove "LICENSE.add")
(if (== st "??")
1
(error "short status of LICENSE should be '??' but not " st))))

; git-status-file cannot detect if a file is renamed
(define (test-git-renamed)
(system "git mv LICENSE LICENSE.renamed")
(with st (git-status-file "LICENSE.renamed" (url-pwd))
(system "git mv LICENSE.renamed LICENSE")
(if (== st "A ")
1
(error "short status of LICENSE.renamed should be 'A ' but not " st))))

(define (test-git-modified)
(system-copy "xmake.lua" "LICENSE")
(system "git add LICENSE")
(with st (git-status-file "LICENSE" (url-pwd))
(system "git reset HEAD LICENSE")
(system "git checkout LICENSE")
(if (== st "M ")
1
(error "short status of LICENSE.renamed should be 'M ' but not " st))))

(define (test-file-modified)
(system-copy "xmake.lua" "LICENSE")
(with st (git-status-file "LICENSE" (url-pwd))
(system "git checkout LICENSE")
(if (== st " M")
1
(error "short status of LICENSE.renamed should be ' M' but not " st))))

(define (test-git-file-modified)
(system-copy "xmake.lua" "LICENSE")
(system "git add LICENSE")
(system-copy "README.md" "LICENSE")
(with st (git-status-file "LICENSE" (url-pwd))
(system "git reset HEAD LICENSE")
(system "git checkout LICENSE")
(if (== st "MM")
1
(error "short status of LICENSE.renamed should be 'MM' but not " st))))

(define (test-unexist)
(with st (git-status-file "not_exist" (url-pwd))
(if (== st "")
1
(error "short status of not_exist should be '' but not " st))))

(tm-define (test_44_7)
(let ((n (+ (test-unmodified)
(test-git-deleted)
(test-file-deleted)
(test-file-ignored)
(test-git-added)
(test-file-added)
(test-git-renamed)
(test-git-modified)
(test-file-modified)
(test-git-file-modified)
(test-unexist))))
(display* "Total: " (object->string n) " tests.\n")
(display "Test suite of 44_7: ok\n")))
75 changes: 67 additions & 8 deletions src/Plugins/Git/git.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "tm_debug.hpp"

#include <git2.h>
#include <git2/status.h>

string
libgit2_version () {
Expand All @@ -23,33 +24,90 @@ libgit2_version () {
static void
show_git_last_error (int error) {
const git_error* e= git_error_last ();
debug_io << "Error " << error << "/" << e->klass << ": " << e->message << LF;
debug_io << "libgit2 error " << error << "/" << e->klass << ": " << e->message
<< LF;
}

string
git_load_blob (string rev, url file_u, url repo_u) {
static bool
check_repo_and_file (url& file_u, url& repo_u) {
if (!is_directory (repo_u)) {
debug_io << repo_u << " is not a valid directory" << LF;
return "";
return false;
}

if (is_rooted (file_u)) {
if (is_regular (file_u) && descends (file_u, repo_u)) {
file_u= (delta (repo_u, file_u))[2];
}
else {
debug_io << file_u << " is not a regular file" << LF;
return "";
return false;
}
}
return true;
}

string
git_status_file (url file_u, url repo_u) {
if (!check_repo_and_file (file_u, repo_u)) return "";

git_repository* repo= NULL;
c_string repo_c (as_string (repo_u));
c_string file_c (as_string (file_u));
int error;
unsigned int status_flags;
char istatus, wstatus;

git_libgit2_init ();
error= git_repository_open (&repo, repo_c);
if (error) {
show_git_last_error (error);
return "";
}
error= git_status_file (&status_flags, repo, file_c);
if (error) {
show_git_last_error (error);
return "";
}
istatus= ' ';
wstatus= ' ';
if (status_flags == GIT_STATUS_CURRENT) {
return string (istatus) * string (wstatus);
}
if (status_flags & GIT_STATUS_INDEX_NEW) istatus= 'A';
if (status_flags & GIT_STATUS_INDEX_MODIFIED) istatus= 'M';
if (status_flags & GIT_STATUS_INDEX_DELETED) istatus= 'D';
// dead branch because there is no rename detection in git_status_file
if (status_flags & GIT_STATUS_INDEX_RENAMED) istatus= 'R';
if (status_flags & GIT_STATUS_INDEX_TYPECHANGE) istatus= 'T';

if (status_flags & GIT_STATUS_WT_NEW) {
if (istatus == ' ') istatus= '?';
wstatus= '?';
}
if (status_flags & GIT_STATUS_WT_MODIFIED) wstatus= 'M';
if (status_flags & GIT_STATUS_WT_DELETED) wstatus= 'D';
// dead branch because there is no rename detection in git_status_file
if (status_flags & GIT_STATUS_WT_RENAMED) wstatus= 'R';
if (status_flags & GIT_STATUS_WT_TYPECHANGE) wstatus= 'T';

if (status_flags & GIT_STATUS_IGNORED) {
istatus= '!';
wstatus= '!';
}

git_libgit2_shutdown ();
return string (istatus) * string (wstatus);
}

string
git_load_blob (string rev, url file_u, url repo_u) {
if (!check_repo_and_file (file_u, repo_u)) return "";

if (!is_regular (repo_u * file_u)) {
debug_io << repo_u * file_u << " is not a regular file" << LF;
return "";
}

git_libgit2_init ();

string ret;
git_repository* repo = NULL;
git_index* index= NULL;
Expand All @@ -59,6 +117,7 @@ git_load_blob (string rev, url file_u, url repo_u) {
c_string repo_c (as_string (repo_u));
c_string rev_c (rev * ":" * as_string (file_u));

git_libgit2_init ();
error= git_repository_open (&repo, repo_c);
if (error) {
show_git_last_error (error);
Expand Down
1 change: 1 addition & 0 deletions src/Plugins/Git/git.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@

string libgit2_version ();
string git_load_blob (string rev, url u, url repo_u= url_none ());
string git_status_file (url file_u, url repo_u);

#endif
9 changes: 9 additions & 0 deletions src/Scheme/Plugins/glue_git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ function main()
"url"
}
},
{
scm_name = "git-status-file",
cpp_name = "git_status_file",
ret_type = "string",
arg_list = {
"url",
"url"
}
},
}
}
end
Expand Down

0 comments on commit bd00a30

Please sign in to comment.