diff --git a/CHANGELOG.md b/CHANGELOG.md index d577d5ab6364..549d87e2ca22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,15 +15,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Propagation setup has been moved from settings to bottom player panel - Additional events like "Debug Info" or "Fit Image" have been added for analitics +- Optional using LFS for git annotation storages (#314) ### Deprecated -- +- "Flip images" flag in the create task dialog will be removed. Rotation functionality in client part have been added instead. ### Removed - ### Fixed - Django 2.1.5 (security fix, https://nvd.nist.gov/vuln/detail/CVE-2019-3498) +- Several scenarious which cause code 400 after undo/redo/save have been fixed (#315) ### Security - diff --git a/cvat/apps/git/git.py b/cvat/apps/git/git.py index ab2f8d0a0410..4085041e2374 100644 --- a/cvat/apps/git/git.py +++ b/cvat/apps/git/git.py @@ -50,6 +50,7 @@ class Git: __diffs_dir = None __annotation_file = None __sync_date = None + __lfs = None def __init__(self, db_git, tid, user): self.__db_git = db_git @@ -66,6 +67,7 @@ def __init__(self, db_git, tid, user): self.__branch_name = 'cvat_{}_{}'.format(tid, self.__task_name) self.__annotation_file = os.path.join(self.__cwd, self.__path) self.__sync_date = db_git.sync_date + self.__lfs = db_git.lfs # Method parses an got URL. @@ -256,6 +258,28 @@ def _accumulate(source, target, target_key): if os.path.exists(self.__annotation_file): os.remove(self.__annotation_file) + # Initialize LFS if need + if self.__lfs: + updated = False + lfs_settings = ["*.xml\tfilter=lfs diff=lfs merge=lfs -text\n", "*.zip\tfilter=lfs diff=lfs merge=lfs -text\n"] + if not os.path.isfile(os.path.join(self.__cwd, ".gitattributes")): + with open(os.path.join(self.__cwd, ".gitattributes"), "w") as gitattributes: + gitattributes.writelines(lfs_settings) + updated = True + else: + with open(os.path.join(self.__cwd, ".gitattributes"), "r+") as gitattributes: + lines = gitattributes.readlines() + for setting in lfs_settings: + if setting not in lines: + updated = True + lines.append(setting) + gitattributes.seek(0) + gitattributes.writelines(lines) + gitattributes.truncate() + + if updated: + self.__rep.git.add(['.gitattributes']) + # Dump an annotation dump(self.__tid, format, scheme, host, OrderedDict()) dump_name = Task.objects.get(pk = self.__tid).get_dump_path() @@ -268,8 +292,6 @@ def _accumulate(source, target, target_key): else: raise Exception("Got unknown annotation file type") - # Setup LFS for *.zip files - self.__rep.git.lfs("track", self.__path) self.__rep.git.add(self.__annotation_file) # Merge diffs @@ -279,12 +301,7 @@ def _accumulate(source, target, target_key): diff = json.loads(f.read()) _accumulate(diff, summary_diff, None) - # Commit and push - self.__rep.index.add([ - '.gitattributes', - ]) self.__rep.index.commit("CVAT Annotation updated by {}. Summary: {}".format(self.__user["name"], str(summary_diff))) - self.__rep.git.push("origin", self.__branch_name, "--force") shutil.rmtree(self.__diffs_dir, True) @@ -344,6 +361,7 @@ def _initial_create(tid, params): db_git.url = git_path db_git.path = path db_git.task = db_task + db_git.lfs = params["use_lfs"].lower() == "true" try: _git = Git(db_git, tid, user) diff --git a/cvat/apps/git/migrations/0003_gitdata_lfs.py b/cvat/apps/git/migrations/0003_gitdata_lfs.py new file mode 100644 index 000000000000..84da1c7ba721 --- /dev/null +++ b/cvat/apps/git/migrations/0003_gitdata_lfs.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.3 on 2019-02-05 17:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('git', '0002_auto_20190123_1305'), + ] + + operations = [ + migrations.AddField( + model_name='gitdata', + name='lfs', + field=models.BooleanField(default=True), + ), + ] diff --git a/cvat/apps/git/models.py b/cvat/apps/git/models.py index d72c921c057e..07a6ece6d50d 100644 --- a/cvat/apps/git/models.py +++ b/cvat/apps/git/models.py @@ -22,3 +22,4 @@ class GitData(models.Model): path = models.CharField(max_length=256) sync_date = models.DateTimeField(auto_now_add=True) status = models.CharField(max_length=20, default=GitStatusChoice.NON_SYNCED) + lfs = models.BooleanField(default=True) diff --git a/cvat/apps/git/static/git/js/dashboardPlugin.js b/cvat/apps/git/static/git/js/dashboardPlugin.js index eff27e10a213..9380ce7396e8 100644 --- a/cvat/apps/git/static/git/js/dashboardPlugin.js +++ b/cvat/apps/git/static/git/js/dashboardPlugin.js @@ -60,6 +60,7 @@ window.cvat.git = { labelStatusId: "gitReposLabelStatus", labelMessageId: "gitReposLabelMessage", createURLInputTextId: "gitCreateURLInputText", + lfsCheckboxId: "gitLFSCheckbox", updateState: () => { let gitWindow = $(`#${window.cvat.git.reposWindowId}`); @@ -136,6 +137,10 @@ document.addEventListener("DOMContentLoaded", () => { `style="width: 90%", placeholder="github.com/user/repos [annotation/.zip]" ` + `title = "Field for a repository URL and a relative path inside the repository. Default repository path is 'annotation/.zip'. There are .zip or .xml extenstions are supported."/>` + ` + + + + ` ).insertAfter($("#dashboardBugTrackerInput").parent().parent()); @@ -145,6 +150,7 @@ document.addEventListener("DOMContentLoaded", () => { let gitPath = $(`#${window.cvat.git.createURLInputTextId}`).prop("value").replace(/\s/g, ""); if (gitPath.length) { oData.append("git_path", gitPath); + oData.append("use_lfs", $(`#${window.cvat.git.lfsCheckboxId}`).prop("checked")); } originalCreateTaskRequest(oData, onSuccessRequest, onSuccessCreate, onError, onComplete, onUpdateStatus); };