2

I'm writing a script for a build script to support both SVN and Git hosted projects. It would be convenient if there is no manual settings for the projects to know which repository type it is.

The build script will be run on a fixed set of build servers, and it will do a clean checkout for each build, or do an update in continuous build mode. Before checking out the repository and doing any pre-build events such as download (or export) a package from a repository, an repository identification step will be proceeded over the repo's URL. Based on the result, a concrete repo wrapper object will be instanced and pass on. The rest part of the build script will use the abstract interface of the repo wrapper to do the repo related job, e.g. checkout, export, get latest revision number, update, check if remote has update.

To identify a repo, I will try a list of known repo, each with a identify function to test the repo's URL.

For a SVN repo, for example, I could use svn info --non-interactive --trust-server-cert https://path/to/repo and check the exit code. It works as expected.

If its failed to detect as a SVN repo, I'll then try with git ls-remote https://path/to/repo but there seems no similar options to disable user interactive when the repo has no saved credential available.

When SVN server is unreachable, it will try detecting whether a SVN repo is a Git repo, and it pops up the credential window and blocks the build script.

I could do something like checking the name of the repo for some special keywords before calling the git commands. But I think there might be better solutions already.

edit:

I think I got a workaround now:

  1. Switch to a user different credential helper, for example store or manager on windows and set git config --global credential.interactive never to prevent the pop up dialog box. And,
  2. Pass linefeed through pipe to the command line git ls-remote https://path/to/repo to skip the prompted username and password.

This works for my case, I'll keep this question for better solutions though.

ZHANG Zikai
  • 560
  • 6
  • 15
  • Some additional questions come to my mind here: (1) What do you intend to do if it is both, or neither? (2) Once you've picked some VCS—whether that's SVN, Git, Mercurial, P4, Bzr, DARCS, or even ClearCase—what will you *do* with that information? (As for question 1, I've actually done this with Git and Mercurial, where one work-tree is used for both VCSes. It's a little bit flaky and you need to know how to tweak things, but it does work.) – torek Jul 19 '16 at 06:28
  • Typically git remote repository paths end in `.git` but that's just convention I believe, and not necessarily true always. Why not just make the request and then see which one works? – Vidur Jul 19 '16 at 06:44
  • @torek I didn't realise there would be repo work for both. If so, return any one would be fine in my scenario. If neither, then, either it is not a valid repo, or we haven't prepared to support that. For question 2, actually what I did in the build script is to generate a repo wrapper object with several commonly used operations appeared in the build script already. I'll write implementation for each repo typs. And this is the 'identify' operation that should be called before the concrete wrapper object is instanced. – ZHANG Zikai Jul 19 '16 at 07:11
  • @Vidur Assuming your request means checkout or clone, if making a request won't ask for credential and block the script, I'd like to use it as well. – ZHANG Zikai Jul 19 '16 at 07:14
  • @ZHANGZikai Not sure what you mean by 'block the script', but yes I mean make the checkout/clone request with the necessary credentials, if it is the right type of repo, the request should succeed, if not try the other type. – Vidur Jul 19 '16 at 07:15
  • @Vidur I expect the build server process projects that have stored credential already. When no matching credential available, git will prompt a window asking for it. That's an interactive step that will waiting for someone to deal with. If it could be skipped automatically like SVN's --non-interactive option, then it's not blocking the script. – ZHANG Zikai Jul 19 '16 at 07:17
  • I'm not sure what you mean by "the 'identify' operation" (there is no `svn identify`, nor is there a `git identify`). Apparently you're looking for something like `svn info` or `svnversion` for the SVN case? (see also http://stackoverflow.com/q/579196/1256452) And maybe `git describe` for the Git case? Note that Git repositories are self-contained so there's no need to consult the upstream; for SVN the picture is more complicated since the actual repository is centralized and all you have is a work-tree. – torek Jul 19 '16 at 16:28
  • @torek Sorry, the identify operation is part of my abstract repo wrapper object. I use `svn info` for identifying SVN repo urls, and I'm trying to use `git ls-remote` to identify Git repo urls. After a repo url is identified, I will then instance a repo object for the rest of operations. Note the identify operation is mean to called before a working copy is checked out or cloned. – ZHANG Zikai Jul 20 '16 at 00:21
  • That just seems like a fundamentally wrong approach for any Distributed VCS (Git, Mercurial, Bzr, etc): half the point of these systems is to *avoid* needing to go anywhere else. Centralized VCSes like SVN require that; but DVCSes generally treat it as a bug, and there may not *be* any other repositories. In any case, perhaps you should just run `git rev-parse --git-dir >/dev/null 2>&1` to test for Git: if it fails, it's not a Git repo. – torek Jul 20 '16 at 03:36
  • @torek What you said about the DVCS is absolutely true, but that aspect of the features happens to be not relevant to my problem. I'll update the question to describe it more clearly. – ZHANG Zikai Jul 20 '16 at 06:08

0 Answers0