haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.61k stars 691 forks source link

source-repository-package branch failure #6888

Open georgefst opened 4 years ago

georgefst commented 4 years ago

With:

source-repository-package
  type: git
  location: git://github.com/georgefst/pretty-simple.git
  branch: experimental

at the top of my cabal.project, I get the failure fatal: '--detach' cannot be used with '-b/-B/--orphan'. Unclear what's causing this. It works fine with master.

git version is 2.7.4, which is pretty old (can't upgrade right now on my work machine), so if that's the issue, I'll just work around it.

phadej commented 4 years ago

An example output

Project settings changed, reconfiguring...
creating /code/public-haskell/tree-diff/dist-newstyle
creating /code/public-haskell/tree-diff/dist-newstyle/cache
/usr/bin/git --version
creating /code/public-haskell/tree-diff/dist-newstyle/src
/usr/bin/git clone --no-checkout 'git://github.com/georgefst/pretty-simple.git' /code/public-haskell/tree-diff/dist-newstyle/src/pretty-si_-3997a25a56f97597
Cloning into '/code/public-haskell/tree-diff/dist-newstyle/src/pretty-si_-3997a25a56f97597'...
remote: Enumerating objects: 55, done.
remote: Counting objects: 100% (55/55), done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 1204 (delta 16), reused 44 (delta 11), pack-reused 1149
Receiving objects: 100% (1204/1204), 288.14 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (514/514), done.
/usr/bin/git checkout --detach --force experimental --
fatal: '--detach' cannot be used with '-b/-B/--orphan'

and looks like we have an unsolved TODO

https://github.com/haskell/cabal/blob/5ce6b08b332fecf4e5100595bbe55edf6060f99c/cabal-install/Distribution/Client/VCS.hs#L628-L629

elldritch commented 4 years ago

For anyone else who arrives at this, you can work around it by cding into the cloned directory in dist-newstyle and manually running the correct git checkout yourself.

georgefst commented 2 years ago

After all this time, I have suddenly accidentally discovered that branch is optional, and if you're specifying tag anyway, fairly pointless. Now that I think about it, it would be weird if this wasn't the case.

Admittedly, now that I look, the documentation clearly states:

This field is optional.

So this issue isn't quite as high priority as I'd thought. Would still be nice though!

liskin commented 2 years ago

@georgefst What if you aren't specifying tag:, though?

georgefst commented 2 years ago

@georgefst What if you aren't specifying tag:, though?

Well, then, as it stands, you can't use branch. I'm not arguing that this issue should be closed. I'm just pointing out for anyone who comes across this that it isn't a show-stopper in many cases.

liskin commented 2 years ago

I see, thanks for the clarification. (I got confused because the example at the top of this issue uses a branch, not a tag, and it's exactly the usecase I'm concerned about.)

tomjaguarpaw commented 2 years ago

I also came across this. On searching for the error fatal: '--detach' cannot be used with '-b/-B/--orphan' I arrived here. To make @georgefst's workaround crystal clear: don't use branch just use tag (which actually means to seem "commit"). For example, in cabal.project:

packages: *

source-repository-package
 type: git
 location: git@github.com:purebred-mua/purebred-email.git
 tag: 19e06063d03c477f33f3add82c1b4f7c6e77b801
georgefst commented 2 years ago

just use tag (which actually means to seem "commit").

I think "tag" is an attempt to use VCS-agnostic terminology. But it is a little confusing since Git has its own separate concept of a "tag".

fgaz commented 2 years ago

maybe "revision" would be a more appropriate name (though changing it is probably more pain than it's worth)

georgefst commented 2 years ago

though changing it is probably more pain than it's worth

Strongly agreed!

tomjaguarpaw commented 2 years ago

Personally I don't agree. tag is sufficiently misleading in the context of git that I think it would be better to provide a less misleading alternative. Perhaps introduce revision or rev and deprecate tag? (Although if tag is used for genuine git tags then it shouldn't be deprecated for that purpose.)

georgefst commented 2 years ago

Fair enough, I can see the argument. This is getting very off-topic though.

purefn commented 2 years ago

After all this time, I have suddenly accidentally discovered that branch is optional, and if you're specifying tag anyway, fairly pointless. Now that I think about it, it would be weird if this wasn't the case.

This wouldn't be weird at all. I would prefer to specify both branch and tag (aka revision), if it meant that cabal would only fetch that specific branch and the changes in it. Most of the time this is the behavior I want, I don't want the whole repository.

tomjaguarpaw commented 2 years ago

I would prefer to specify both branch and tag (aka revision), if it meant that cabal would only fetch that specific branch and the changes in it. Most of the time this is the behavior I want, I don't want the whole repository.

Specifying the branch has no relation to how much of the repository cabal (or rather git run by cabal) will fetch.

purefn commented 2 years ago

Specifying the branch has no relation to how much of the repository cabal (or rather git run by cabal) will fetch.

I'm aware of that, but it should is what I was trying to get at.

tomjaguarpaw commented 2 years ago

Hmm, should it? I don't see the connection between specifying the branch name and how much of the repository cabal should fetch.

purefn commented 2 years ago

Oh, it absolutely does (or can). Instead of doing a full clone, you would just do something like

$ git clone -b mybranch --single-branch git@github.com:purefn/myrepo

Instead of fetching all the branches and tags and all revisions in the repo, that gives you just that branch, its files, and its history - which can save significantly on time, bandwidth, and disk space. As an example, this is how nix typically clones git repos and it is able to clone repos much more rapidly than stack or cabal, both of which have to do a full clone because you can only specify the revision you want. Some hardliners would argue that this is the way that git (and other DVCSs) is meant to be used.

tomjaguarpaw commented 2 years ago

Yes indeed that would be a nice feature. The reason that I said I don't see the connection is that commit hashes can be shallow-fetched too, not just branches or tags:

% git init && git remote add origin https://github.com/haskell/cabal.git                 
% git fetch --depth 1 origin af6290ed92854671eaa65769b757691b521b1859 
remote: Enumerating objects: 3272, done.
remote: Counting objects: 100% (3272/3272), done.
remote: Compressing objects: 100% (2521/2521), done.
remote: Total 3272 (delta 480), reused 2007 (delta 301), pack-reused 0
Receiving objects: 100% (3272/3272), 2.35 MiB | 8.73 MiB/s, done.
Resolving deltas: 100% (480/480), done.
From https://github.com/haskell/cabal
 * branch            af6290ed92854671eaa65769b757691b521b1859 -> FETCH_HEAD

EDIT: I was mistaken that this functionality had been removed from git.

However, that functionality seems to have been removed at some point during git's evolution, sadly.

This is rather frustrating since fetching a branch name (or even a tag) is not reproducible, but fetching a commit hash is. Therefore we would ideally want to shallow-fetch commit hashes!

tomjaguarpaw commented 2 years ago

Having said that, someone has, in the last four months, created a go program to do shallow fetches by sha so this recipe must work with at least some git servers. Theoretically cabal could try to shallow fetch first and then do a full fetch if shallow doesn't work (but I don't wish that maintenance burden on the cabal developers).

EDIT: this comment is now somewhat redundant

tomjaguarpaw commented 2 years ago

Update: it is possible to shallow-fetch commit hashes, as long as the server enables support for it, which GitHub does, for example, and as long as you use the full, unabbreviated commit hash. See my edits above.

purefn commented 2 years ago

Yes, you can do that as long as the commit is on the default branch. As far as I'm aware, if it is not on the default branch, then it will not work.

tomjaguarpaw commented 2 years ago

Here's an example of fetching from a commit that is on freeze-docs and not on the default branch (master):

% git init && git remote add origin https://github.com/haskell/cabal.git
% git fetch --depth 1 origin c4230704d739115a13284d8f713b8ef781309d5b
remote: Enumerating objects: 3266, done.
remote: Counting objects: 100% (3266/3266), done.
remote: Compressing objects: 100% (2518/2518), done.
remote: Total 3266 (delta 480), reused 1998 (delta 299), pack-reused 0
Receiving objects: 100% (3266/3266), 2.34 MiB | 8.78 MiB/s, done.
Resolving deltas: 100% (480/480), done.
From https://github.com/haskell/cabal
 * branch            c4230704d739115a13284d8f713b8ef781309d5b -> FETCH_HEAD
tomjaguarpaw commented 2 years ago

(Admittedly you can only fetch commits that are on some branch, but that's a much less severe requirement.)

purefn commented 2 years ago

Holy cow! I wish all tools did it this way! The amount of time I've spent waiting for both stack and cabal to do full clones of git repos can literally be counted in days. If they did this that would probably cut it down to less than an hour.

tomjaguarpaw commented 2 years ago

Yeah, this feature seems desirable and simple enough that I'm willing to proclaim I want to implement it (but then probably not actually implement it).

jneira commented 2 years ago

hi, after https://github.com/haskell/cabal/pull/7625 the code started to use git reset instead git checkout and now the error is different, with this cabal.project:

packages: .

source-repository-package
  type: git
  location: https://github.com/georgefst/pretty-simple.git
  branch: web

i got:

Running: "D:\dev\app\git\cmd\git.exe" "clone" "--no-checkout" "https://github.com/georgefst/pretty-simple.git" "D:\dev\ws\haskell\issues\6888\dist-newstyle\src\pretty-si_-592d60f12a0e425"
Running: "D:\dev\app\git\cmd\git.exe" "submodule" "deinit" "--force" "--all"
Running: "D:\dev\app\git\cmd\git.exe" "reset" "--hard" "web" "--"
fatal: Failed to resolve 'web' as a valid revision.

It continues working with master. I think the underlying problem is the same though but i wanted to update the info

noinia commented 1 year ago

I finally got sufficiently annoyed by this issue that I decided to fix it..... (at least for git repos)

soulomoon commented 5 months ago

Same here, it is making hard to run the pipeline in HLS with LSP package changed