dirk-thomas / vcstool

Vcstool is a command line tool designed to make working with multiple repositories easier
Apache License 2.0
404 stars 85 forks source link

export includes basename if the passed path is a repository itself #177

Open jenisys opened 3 years ago

jenisys commented 3 years ago

VERSION: vcs 0.2.15 (installed via pypi.org)

If I import my ".rosinstall" file with vcs and export it again, the repo-names have the basename (example: "alice") of the current git-repo as prefix. Therefore, if I import the exported repository-description again and use "vcs pull", all my sub-repo and a new directory-tree "alice/..." with a copy of my sub-repositories.

Currently, there seems no way for me to strip the basename during "vcs export". I need to manually strip in the editor (or with sed, ...).

EXAMPLE:

# -- FILE: alice/.repos
repositories:
  lib/doctest:
    type: git
    url: https://github.com/onqtam/doctest.git
# -- PREPARE: The base-repo "alice"
$ mkdir alice && cd alice && git init
$ edit .repos # CREATE-FILE: ".repos" with contents of file above.
$ git add .repos
$ git commit -m"INITIAL" .repos

$ vcs import --input=.repos
# POSTCONDITION: "lib/doctest/" exists (cloned from github-repo).

$ vcs export -n
repositories:
  alice/lib/doctest:
    type: git
    url: https://github.com/onqtam/doctest.git
    version: master
...

EXPECTED:

repositories:
  lib/doctest:
    type: git
    url: https://github.com/onqtam/doctest.git
    version: master
# -- HINT: SAME AS FILE: alice/.repos (above)

Therefore, if I use the exported repo-description, I will get another set of my sub-repos under new "alice/" sub-directory:

$ vcs export -n > .repos_2
$ vcs import --input=.repos_2
# -- POSTCONDITION: ./alice/lib/doctest/ exists (which is SAD)

DESIRED CHANGE: There should be at least a command-line option like: vcs export -n --remove-prefix=alice/.

SIMILAR TO:

dirk-thomas commented 3 years ago

I think the problem of your use case comes from invoking vcs export in the root of the git repository alice. I would expect it to work just fine if you invoke it in the parent directory instead. Can you please try that and comment if that works.

Otherwise the .repos file would contain an entry . which would imply when vcs import is invoked that something is clone into the current working directory. That is a use case never considered / supported.

jenisys commented 3 years ago

Yes, I may have a special use case. BUT: Otherwise, I disagree.

This is basically a problem of prefix management. When you use "vcs import src --input=whatever.repos", I would assume that "src/..." directory structure is created and the exported info should show that (relative to my current working directory). Therefore, the name of my current directory should never be the prefix in the exported repository.paths.

In addition, the import-export cycle must always be idempotent. Otherwise, you get the problems that I currently have. You can say that it normally works. This is true with the exception of the one spot, I am pointing you here. This is currently left unsolved.

wstool had the better approach here. It showed the repo of the current working directory and suggested that you should add it, but it left this decision up to the user.

NOTE: The problem was probably introduced by the PR #102 that I mentioned above. Therefore, it was at least considered when this code was written.

POINT: Current working directory is always contained in repository list (if I use: or ".") There is a remedy by providing an vcs export -n --exclude=. (for example).

USECASE (for my problem): Provide a Git repository (ANCHER-REPO) with all the repo-description files for all users/developers resulting in many combinations of workspace variants for multiple teams. The user/developer clones the ANCHOR-REPO and can then setup his/her workspace depending in which team he/she is currently participating. I think Google repo-tool (used for Android development and others) takes a similar approach.

dirk-thomas commented 3 years ago

Yes, I may have a special use case. This is basically a problem of prefix management.

My comment was only trying to point out that import/export is idempotent already - except in this very specific case where the root is a repository. That special case can certainly be fixed. Are you interested in contributing a pull request for this?

wstool had the better approach here. It showed the repo of the current working directory and suggested that you should add it, but it left this decision up to the user.

wstool maintained redundant (and potentially out of sync) state information which vcstool is intentionally not doing. For vcstool the only "truth" is the filesystem.

Current working directory is always contained in repository list

Imo a potential option export --exclude ... is orthogonal and can be considered independent of this ticket.

yajo commented 2 years ago

I think that the issue is valid. The result is unexpected.

For example, in a git repo, where the local folder is called test, and that contains these repos:

$ tree -dL 2
.
└── repos
    ├── autopretty-a
    └── autopretty-b

3 directories

Exporting without dir, or with . as dir, adds the unexpected extra test/ prefix:

$ vcs export -n
repositories:
  test/repos/autopretty-a:
    type: git
    url: https://github.com/copier-org/autopretty
    version: main
  test/repos/autopretty-b:
    type: git
    url: https://github.com/copier-org/autopretty
    version: main
test: Could not determine ref: fatal: no upstream configured for branch 'main'

$ vcs export -n .
repositories:
  test/repos/autopretty-a:
    type: git
    url: https://github.com/copier-org/autopretty
    version: main
  test/repos/autopretty-b:
    type: git
    url: https://github.com/copier-org/autopretty
    version: main
test: Could not determine ref: fatal: no upstream configured for branch 'main'

... but when you add repos path, it removes both test and repos from the prefix:

$ vcs export -n repos
repositories:
  autopretty-a:
    type: git
    url: https://github.com/copier-org/autopretty
    version: main
  autopretty-b:
    type: git
    url: https://github.com/copier-org/autopretty
    version: main

So, it's inconsistent. It should either add the prefix always, or remove it always.

IMHO the prefix should not be added by default, because this simple flow fails:

vcs export -n | vcs import

This other flow works, however. But again, it doesn't make much sense that works where the previous one fails:

vcs export -n repos | vcs import repos
yajo commented 2 years ago

I think the problem of your use case comes from invoking vcs export in the root of the git repository alice. I would expect it to work just fine if you invoke it in the parent directory instead.

BTW this workflow is kinda weird IMHO.

You can't predict which will be the name of the cloned folder in your colleague's PC, so if they clone the main repo that contains the clone definitions in a folder with a different name, it will fail.