commit - 01a44956166c76e44f58809e5a1ea1477adfef80
commit + 7154f6ce0618e7d8582cd42d577f01cbc3c18d16
blob - 9538b04b4710bad47462be5278aeea7bd4768ac2
blob + 265c9850b620a3a3ca13d48618052cfb435aadff
--- got/got.1
+++ got/got.1
.It M Ta modified file
.It A Ta file scheduled for addition in next commit
.It D Ta file scheduled for deletion in next commit
+.It C Ta modified or added file which contains merge conflicts
.It ! Ta versioned file was expected on disk but is missing
.It ~ Ta versioned file is obstructed by a non-regular file
.It ? Ta unversioned item not tracked by
blob - b6b518579e34e85b27052c4b28680fef25d63669
blob + 4a3c791020dff8d53212a4d0fac32cd6b5925676
--- got/got.c
+++ got/got.c
struct stat sb;
if (status != GOT_STATUS_MODIFY && status != GOT_STATUS_ADD &&
- status != GOT_STATUS_DELETE)
+ status != GOT_STATUS_DELETE && status != GOT_STATUS_CONFLICT)
return NULL;
if (!a->header_shown) {
a->header_shown = 1;
}
- if (status == GOT_STATUS_MODIFY || status == GOT_STATUS_DELETE) {
+ if (status != GOT_STATUS_ADD) {
err = got_object_open_as_blob(&blob1, a->repo, id, 8192);
if (err)
goto done;
}
- if (status == GOT_STATUS_MODIFY || status == GOT_STATUS_ADD) {
+ if (status != GOT_STATUS_DELETE) {
if (asprintf(&abspath, "%s/%s",
got_worktree_get_root_path(a->worktree), path) == -1) {
err = got_error_from_errno();
blob - cd22378a777b353c7f39ca3b244c95414d187c8a
blob + 5d07d5a5961de07dae868ca1e72e47e990d7620d
--- lib/worktree.c
+++ lib/worktree.c
#include <fnmatch.h>
#include <libgen.h>
#include <uuid.h>
+#include <util.h>
#include "got_error.h"
#include "got_repository.h"
return err;
}
+/* Upgrade STATUS_MODIFY to STATUS_CONFLICT if a conflict marker is found. */
static const struct got_error *
+get_modified_file_content_status(unsigned char *status, FILE *f)
+{
+ const struct got_error *err = NULL;
+ const char *markers[3] = {
+ GOT_DIFF_CONFLICT_MARKER_BEGIN,
+ GOT_DIFF_CONFLICT_MARKER_SEP,
+ GOT_DIFF_CONFLICT_MARKER_END
+ };
+ int i = 0;
+ char *line;
+ size_t len;
+ const char delim[3] = {'\0', '\0', '\0'};
+
+ while (*status == GOT_STATUS_MODIFY) {
+ line = fparseln(f, &len, NULL, delim, 0);
+ if (line == NULL) {
+ if (feof(f))
+ break;
+ err = got_ferror(f, GOT_ERR_IO);
+ break;
+ }
+
+ if (strncmp(line, markers[i], strlen(markers[i])) == 0) {
+ if (markers[i] == GOT_DIFF_CONFLICT_MARKER_END)
+ *status = GOT_STATUS_CONFLICT;
+ else
+ i++;
+ }
+ }
+
+ return err;
+}
+
+static const struct got_error *
get_file_status(unsigned char *status, struct stat *sb,
struct got_fileindex_entry *ie, const char *abspath,
struct got_repository *repo)
const uint8_t *bbuf = got_object_blob_get_read_buf(blob);
err = got_object_blob_read_block(&blen, blob);
if (err)
- break;
+ goto done;
/* Skip length of blob object header first time around. */
flen = fread(fbuf, 1, sizeof(fbuf) - hdrlen, f);
if (flen == 0 && ferror(f)) {
err = got_error_from_errno();
- break;
+ goto done;
}
if (blen == 0) {
if (flen != 0)
}
hdrlen = 0;
}
+
+ if (*status == GOT_STATUS_MODIFY) {
+ rewind(f);
+ err = get_modified_file_content_status(status, f);
+ }
done:
if (blob)
got_object_blob_close(blob);
blob - 84bbf2e8d42e2b4bfd8d1ad97db33cc0361a41d7
blob + 6153d36c2d585a109a3c72d16d412dda24c7d84e
--- regress/cmdline/status.sh
+++ regress/cmdline/status.sh
fi
test_done "$testroot" "$ret"
}
+
+function test_status_shows_conflict {
+ local testroot=`test_init status_shows_conflict 1`
+ echo "1" > $testroot/repo/numbers
+ echo "2" >> $testroot/repo/numbers
+ echo "3" >> $testroot/repo/numbers
+ echo "4" >> $testroot/repo/numbers
+ echo "5" >> $testroot/repo/numbers
+ echo "6" >> $testroot/repo/numbers
+ echo "7" >> $testroot/repo/numbers
+ echo "8" >> $testroot/repo/numbers
+ (cd $testroot/repo && git add numbers)
+ git_commit $testroot/repo -m "added numbers file"
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ sed -i 's/2/22/' $testroot/repo/numbers
+ git_commit $testroot/repo -m "modified line 2"
+
+ # modify line 2 in a conflicting way
+ sed -i 's/2/77/' $testroot/wt/numbers
+
+ echo "C numbers" > $testroot/stdout.expected
+ echo -n "Updated to commit " >> $testroot/stdout.expected
+ git_show_head $testroot/repo >> $testroot/stdout.expected
+ echo >> $testroot/stdout.expected
+
+ (cd $testroot/wt && got update > $testroot/stdout)
+
+ cmp $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo 'C numbers' > $testroot/stdout.expected
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+
+ cmp $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_status_basic
run_test test_status_subdir_no_mods
run_test test_status_subdir_no_mods2
run_test test_status_unversioned_subdirs
run_test test_status_ignores_symlink
run_test test_status_shows_no_mods_after_complete_merge
+run_test test_status_shows_conflict