Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refs/stash@0 is not a valid reference #1121

Closed
ext opened this issue Mar 18, 2022 · 20 comments · Fixed by #1178
Closed

refs/stash@0 is not a valid reference #1121

ext opened this issue Mar 18, 2022 · 20 comments · Fixed by #1178

Comments

@ext
Copy link

ext commented Mar 18, 2022

Description

$ npm exec lint-staged
√ Preparing lint-staged...
√ Running tasks for staged files...
√ Applying modifications from tasks...
× error: refs/stash@0 is not a valid reference

× lint-staged failed due to a git error.
Any lost modifications can be restored from a git stash:

> git stash list
stash@{0}: automatic lint-staged backup
> git stash apply --index stash@{0}

Running lint-staged@123.7 under MSYS2 in Windows 10 but otherwise nothing fancy.

Debug Logs

expand to view
2022-03-18T17:05:51.935Z lint-staged:bin Running `lint-staged@12.3.7`
2022-03-18T17:05:51.935Z lint-staged:bin Options parsed from command-line: {
  allowEmpty: false,
  concurrent: true,
  configPath: undefined,
  cwd: undefined,
  debug: true,
  maxArgLength: 4095.5,
  quiet: false,
  relative: false,
  shell: false,
  stash: true,
  verbose: false
}
2022-03-18T17:05:51.937Z lint-staged:validateOptions Validating options...
2022-03-18T17:05:51.937Z lint-staged:validateOptions Validated options!
2022-03-18T17:05:51.937Z lint-staged Unset GIT_LITERAL_PATHSPECS (was `undefined`)
2022-03-18T17:05:51.937Z lint-staged:runAll Running all linter scripts...
2022-03-18T17:05:51.937Z lint-staged:runAll Using working directory `C:\path\to\repo`
2022-03-18T17:05:51.938Z lint-staged:resolveGitRepo Resolving git repo from `C:\path\to\repo`
2022-03-18T17:05:51.938Z lint-staged:resolveGitRepo Unset GIT_DIR (was `undefined`)
2022-03-18T17:05:51.938Z lint-staged:resolveGitRepo Unset GIT_WORK_TREE (was `undefined`)
2022-03-18T17:05:51.938Z lint-staged:execGit Running git command [ 'rev-parse', '--show-prefix' ]
2022-03-18T17:05:52.086Z lint-staged:resolveGitRepo Resolved git directory to be `C:/path/to/repo`
2022-03-18T17:05:52.086Z lint-staged:resolveGitRepo Resolved git config directory to be `C:/path/to/repo/.git`
2022-03-18T17:05:52.086Z lint-staged:execGit Running git command [ 'log', '-1' ]
2022-03-18T17:05:52.248Z lint-staged:execGit Running git command [ 'diff', '--staged', '--diff-filter=ACMR', '--name-only', '-z' ]
2022-03-18T17:05:52.393Z lint-staged:runAll Loaded list of staged files in git:
[
  'C:/path/to/repo/package-lock.json',
  'C:/path/to/repo/package.json'
]
2022-03-18T17:05:52.393Z lint-staged:getConfigGroups Grouping configuration files...
2022-03-18T17:05:52.393Z lint-staged:getConfigGroups Grouping staged files by their directories...
2022-03-18T17:05:52.393Z lint-staged:getConfigGroups Grouped staged files into 1 directories:
2022-03-18T17:05:52.395Z lint-staged:getConfigGroups {
  'C:\\path\\to\\repo': [ 'C:/path/to/repo/package-lock.json', 'C:/path/to/repo/package.json' ]
}
2022-03-18T17:05:52.395Z lint-staged:getConfigGroups Searching config files...
2022-03-18T17:05:52.395Z lint-staged:loadConfig Searching for configuration from `C:\path\to\repo`...
2022-03-18T17:05:52.396Z lint-staged:loadConfig Successfully loaded config from `C:\path\to\repo\package.json`:
{ '*.{js,json,md,ts}': 'prettier --write' }
2022-03-18T17:05:52.396Z lint-staged:getConfigGroups Found new config "C:\path\to\repo\package.json" from "C:\path\to\repo"!
2022-03-18T17:05:52.396Z lint-staged:validateConfig Validating config from `C:\path\to\repo\package.json`...
2022-03-18T17:05:52.397Z lint-staged:validateConfig Validated config from `C:\path\to\repo\package.json`:
2022-03-18T17:05:52.397Z lint-staged:validateConfig {
  '*.{js,json,md,ts}': 'prettier --write'
}
2022-03-18T17:05:52.397Z lint-staged:loadConfig Searching for configuration from `C:\path\to\repo`...
2022-03-18T17:05:52.398Z lint-staged:loadConfig Successfully loaded config from `C:\path\to\repo\package.json`:
{ '*.{js,json,md,ts}': 'prettier --write' }
2022-03-18T17:05:52.398Z lint-staged:getConfigGroups Found existing config "C:\path\to\repo\package.json" from "C:\path\to\repo"!
2022-03-18T17:05:52.398Z lint-staged:getConfigGroups Grouped staged files into 1 groups!
2022-03-18T17:05:52.398Z lint-staged:execGit Running git command [ 'ls-files', '-z', '--full-name' ]
2022-03-18T17:05:52.535Z lint-staged:execGit Running git command [ 'ls-files', '-z', '--full-name', '--others', '--exclude-standard' ]
2022-03-18T17:05:52.680Z lint-staged:loadConfig Loading configuration from `C:/path/to/repo/package.json`...
2022-03-18T17:05:52.682Z lint-staged:loadConfig Successfully loaded config from `C:\path\to\repo\package.json`:
{ '*.{js,json,md,ts}': 'prettier --write' }
2022-03-18T17:05:52.682Z lint-staged:validateConfig Validating config from `C:\path\to\repo\package.json`...
2022-03-18T17:05:52.682Z lint-staged:validateConfig Validated config from `C:\path\to\repo\package.json`:
2022-03-18T17:05:52.682Z lint-staged:validateConfig {
  '*.{js,json,md,ts}': 'prettier --write'
}
2022-03-18T17:05:52.682Z lint-staged:runAll Found 1 configs:
{
  'C:\\path\\to\\repo\\package.json': { '*.{js,json,md,ts}': 'prettier --write' }
}
2022-03-18T17:05:52.683Z lint-staged:chunkFiles Resolved an argument string length of 90 characters from 2 files
2022-03-18T17:05:52.683Z lint-staged:chunkFiles Creating 1 chunks for maxArgLength of 4095.5
2022-03-18T17:05:52.683Z lint-staged:generateTasks Generating linter tasks
2022-03-18T17:05:52.686Z lint-staged:generateTasks Generated task:
{
  pattern: '*.{js,json,md,ts}',
  commands: 'prettier --write',
  fileList: [
    'C:/path/to/repo/package-lock.json',
    'C:/path/to/repo/package.json'
  ]
}
2022-03-18T17:05:52.686Z lint-staged:makeCmdTasks Creating listr tasks for commands 'prettier --write'
2022-03-18T17:05:52.688Z lint-staged:resolveTaskFn cmd: prettier
2022-03-18T17:05:52.688Z lint-staged:resolveTaskFn args: [ '--write' ]
2022-03-18T17:05:52.688Z lint-staged:resolveTaskFn execaOptions: {
  cwd: 'C:\\path\\to\\repo',
  preferLocal: true,
  reject: false,
  shell: false
}
2022-03-18T17:05:52.688Z lint-staged:chunkFiles Resolved an argument string length of 90 characters from 2 files
2022-03-18T17:05:52.689Z lint-staged:chunkFiles Creating 1 chunks for maxArgLength of 4095.5
[STARTED] Preparing lint-staged...
2022-03-18T17:05:52.691Z lint-staged:GitWorkflow Backing up original state...
2022-03-18T17:05:52.692Z lint-staged:GitWorkflow Getting partially staged files...
2022-03-18T17:05:52.692Z lint-staged:execGit Running git command [ 'status', '-z' ]
2022-03-18T17:05:52.847Z lint-staged:GitWorkflow Found partially staged files: [ 'package.json' ]
2022-03-18T17:05:52.847Z lint-staged:execGit Running git command [
  'diff',
  '--binary',
  '--unified=0',
  '--no-color',
  '--no-ext-diff',
  '--src-prefix=a/',
  '--dst-prefix=b/',
  '--patch',
  '--submodule=short',
  '--output',
  'C:\\path\\to\\repo\\.git\\lint-staged_unstaged.patch',
  '--',
  'package.json'
]
2022-03-18T17:05:52.993Z lint-staged:GitWorkflow Backing up merge state...
2022-03-18T17:05:52.993Z lint-staged:file Reading file `C:\path\to\repo\.git\MERGE_HEAD`
2022-03-18T17:05:52.993Z lint-staged:file Reading file `C:\path\to\repo\.git\MERGE_MODE`
2022-03-18T17:05:52.993Z lint-staged:file Reading file `C:\path\to\repo\.git\MERGE_MSG`
2022-03-18T17:05:52.993Z lint-staged:file File `C:\path\to\repo\.git\MERGE_HEAD` doesn't exist, ignoring...
2022-03-18T17:05:52.993Z lint-staged:file File `C:\path\to\repo\.git\MERGE_MODE` doesn't exist, ignoring...
2022-03-18T17:05:52.994Z lint-staged:file File `C:\path\to\repo\.git\MERGE_MSG` doesn't exist, ignoring...
2022-03-18T17:05:52.994Z lint-staged:GitWorkflow Done backing up merge state!
2022-03-18T17:05:52.994Z lint-staged:GitWorkflow Getting deleted files...
2022-03-18T17:05:52.994Z lint-staged:execGit Running git command [ 'ls-files', '--deleted' ]
2022-03-18T17:05:53.130Z lint-staged:GitWorkflow Found deleted files: []
2022-03-18T17:05:53.131Z lint-staged:execGit Running git command [ 'stash', 'create' ]
2022-03-18T17:05:53.410Z lint-staged:execGit Running git command [
  'stash',
  'store',
  '--quiet',
  '--message',
  'lint-staged automatic backup',
  '9203a6ce04636a2f320ae4c9529d69dd777632fc'
]
2022-03-18T17:05:53.553Z lint-staged:GitWorkflow Done backing up original state!
[SUCCESS] Preparing lint-staged...
[STARTED] Hiding unstaged changes to partially staged files...
2022-03-18T17:05:53.554Z lint-staged:execGit Running git command [ 'checkout', '--force', '--', 'package.json' ]
[SUCCESS] Hiding unstaged changes to partially staged files...
[STARTED] Running tasks for staged files...
[STARTED] package.json — 2 files
[STARTED] *.{js,json,md,ts} — 2 files
[STARTED] prettier --write
[SUCCESS] prettier --write
[SUCCESS] *.{js,json,md,ts} — 2 files
[SUCCESS] package.json — 2 files
[SUCCESS] Running tasks for staged files...
[STARTED] Applying modifications from tasks...
2022-03-18T17:05:54.131Z lint-staged:GitWorkflow Adding task modifications to index...
2022-03-18T17:05:54.131Z lint-staged:execGit Running git command [
  'add',
  '--',
  'C:/path/to/repo/package-lock.json',
  'C:/path/to/repo/package.json'
]
2022-03-18T17:05:54.288Z lint-staged:GitWorkflow Done adding task modifications to index!
2022-03-18T17:05:54.288Z lint-staged:execGit Running git command [ 'diff', '--name-only', '--cached' ]
[SUCCESS] Applying modifications from tasks...
[STARTED] Restoring unstaged changes to partially staged files...
2022-03-18T17:05:54.436Z lint-staged:GitWorkflow Restoring unstaged changes...
2022-03-18T17:05:54.436Z lint-staged:execGit Running git command [
  'apply',
  '-v',
  '--whitespace=nowarn',
  '--recount',
  '--unidiff-zero',
  'C:\\path\\to\\repo\\.git\\lint-staged_unstaged.patch'
]
[SUCCESS] Restoring unstaged changes to partially staged files...
[STARTED] Cleaning up temporary files...
2022-03-18T17:05:54.586Z lint-staged:GitWorkflow Dropping backup stash...
2022-03-18T17:05:54.586Z lint-staged:execGit Running git command [ 'stash', 'list' ]
2022-03-18T17:05:54.831Z lint-staged:execGit Running git command [ 'stash', 'drop', '--quiet', 'refs/stash@{0}' ]
[FAILED] error: refs/stash@0 is not a valid reference

  × lint-staged failed due to a git error.
  Any lost modifications can be restored from a git stash:

    > git stash list
    stash@{0}: automatic lint-staged backup
    > git stash apply --index stash@{0}

Environment

  • OS: Windows 10, MSYS2
  • Node.js: 14.17.5
  • Git: 2.35.1
  • lint-staged: 12.3.7
@iiroj
Copy link
Member

iiroj commented Mar 23, 2022

What's your shell, MSYS2? I haven't heard about that.

I assume it parses something differently, because from your logs we can see this:

lint-staged:execGit Running git command [ 'stash', 'drop', '--quiet', 'refs/stash@{0}' ]
[FAILED] error: refs/stash@0 is not a valid reference

@devinrhode2
Copy link

I wonder if the curly braces are being interpreted by some layer.

@ext if you open ./node_modules/lint-staged and search for this refs/stash@{0} bit
...try changing it to something obviously valid and invalid, and also verify by directly running the final git command

Escaping the curly braces may fix the issue

@ext
Copy link
Author

ext commented Apr 4, 2022

I wonder if the curly braces are being interpreted by some layer.

@ext if you open ./node_modules/lint-staged and search for this refs/stash@{0} bit ...try changing it to something obviously valid and invalid, and also verify by directly running the final git command

Running git stash drop --quiet refs/stash@{0} directly on commandline works.

Escaping the curly braces may fix the issue

That actually does the trick, I've modified lib/gitWorkflow.js as following:

-    return `refs/stash@{${index}}`
+    return `refs/stash@\\{${index}\\}`

With that modification everything now works as expected:

$ npm exec lint-staged
√ Preparing lint-staged...
√ Hiding unstaged changes to partially staged files...
√ Running tasks for staged files...
√ Applying modifications from tasks...
√ Restoring unstaged changes to partially staged files...
√ Cleaning up temporary files...

I dont know if that is a reasonable change or the proper location for it. I could try running the test-cases in this repo and create a PR if you want.

What's your shell, MSYS2? I haven't heard about that.

MSYS2 is using mintty as terminal and bash as shell.

@iiroj
Copy link
Member

iiroj commented Apr 4, 2022

@ext if you open a PR, we can run the integration tests on all platform and see if they pass.

ext added a commit to ext/lint-staged that referenced this issue Apr 5, 2022
@ext
Copy link
Author

ext commented Apr 5, 2022

The change causes the integration tests to fail on other platforms, I'm going to look a bit deeper at the call to execa and if I can reproduce the issue without lint-staged.

https://github.com/ext/lint-staged/runs/5838527402?check_suite_focus=true

@devinrhode2
Copy link

devinrhode2 commented Apr 6, 2022

You could simply check for your specific terminal and escape things appropriately.

I think we chalk it up to git stash using a syntax that happens to be identical to bash.

There's probably a different syntax, instead of stash@{0} maybe something like refs/stashes/0 works idk

@wangrongding
Copy link

I don't want to do a git stash when it fails,How to avoid this from happening?

image

👇

stash@{0}: lint-staged automatic backup

@iiroj
Copy link
Member

iiroj commented May 31, 2022

@wangrongding use --no-stash.

@wangrongding
Copy link

@wangrongding use --no-stash.

Ha ha~ I didn't read the doc.
💗thansks

@ext
Copy link
Author

ext commented Jun 13, 2022

The change causes the integration tests to fail on other platforms, I'm going to look a bit deeper at the call to execa and if I can reproduce the issue without lint-staged.

Took me a while to get some time to investigate further, still not sure what the issue is but it seems like git itself is at fault somehow.

const execa = require("execa");

async function run(cmd, args) {
    const { stdout } = await execa(cmd, args);
    console.log(stdout);
}

async function test1() {
    console.log('test 1 - node');
    await run("node", ["-p", "process.argv.slice(1)", "refs/stash@{0}"]);
}

async function test2() {
    console.log('test 2 - git');
    await run("git", ["show", "refs/stash@{0}"]);
}

(async () =>{
    await test1();
    await test2();
})();

I use code similar to execGit.js and gradually removed/changed things until only the bare minimal was left. Running the above script produces the output:

test 1 - node
[ 'refs/stash@{0}' ]
test 2 - git
...\node_modules\execa\lib\error.js:60
error = new Error(message);
^

Error: Command failed with exit code 128: git show refs/stash@{0}
fatal: ambiguous argument 'refs/stash@0': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
...

Running git show refs/stash@{0} on CLI works as expected.

-    await run("git", ["show", "refs/stash@{0}"]);
+    await run("bash", ["-c", "git show refs/stash@{0}"]);

Similarly using bash -c works as expected.

The issue doesn't appear to be within lint-staged at all but I'm still at a loss for what to do. I'd gladly help any way I can, should I file this as a bug to execa instead?

@okonet
Copy link
Collaborator

okonet commented Jun 13, 2022

By looking at your output it seems that the first commands argument get evaluated somehow. Can this be the case?

@ext
Copy link
Author

ext commented Jun 13, 2022

By looking at your output it seems that the first commands argument get evaluated somehow. Can this be the case?

Probable, any suggestion to how to confirm that? As with earlier comments, escaping { and } helps (but breaks other platforms)

-    await run("git", ["show", "refs/stash@{0}"]);
+    await run("git", ["show", "refs/stash@\\{0\\}"]);

I tried switching out execa with spawn from child_process, same result:

fatal: ambiguous argument 'refs/stash@0': unknown revision or path not in the working tree.

I appreciate you all taking time to assist with this even if it isn't bug in this software ❤️

@okonet
Copy link
Collaborator

okonet commented Jun 13, 2022

Can it be bash-related?

@iiroj
Copy link
Member

iiroj commented Jun 13, 2022

If we can detect MSYS2, then we could conditionally escape the characters. Maybe there's something in the process.env for this... A PR is welcome!

@devinrhode2
Copy link

I fished around for a refs/stashes/0 type syntax, but didn't find anything :(
Typing git show refs/Tab showed all the possibilities. There IS simply git show refs/stash, which refers to the "latest" stash.. but I'm not sure if we can use this.

I think learning what execa is doing, reading execa docs, etc, is the way to go. It's a decent package, but it's very full featured and I've found reading the docs to be quite important.

@devinrhode2
Copy link

In theory git commits can function as "stashes", but that would probably require a bit of re-work

@iiroj
Copy link
Member

iiroj commented Jun 14, 2022

It might be possible to use git stash create which returns the hash (for reuse later) along with git stash store. The problem is, we don't currently require/enforce a specific git version, so the switch might become a breaking change for some users of a very old version.

@devinrhode2
Copy link

which git version would that require?

@devinrhode2
Copy link

devinrhode2 commented Jun 16, 2022

Also check this out: https://stackoverflow.com/a/41008657/565877

We can manually create refs

May be nicer than stashes

@msand
Copy link

msand commented Feb 2, 2023

I have a similar issue, tried doing development on a windows machine today and got this error, fixed it by adding:

    if (!!process.env.PSModulePath && !!process.env.WINDIR) {
      return `${index}`
    }

Below the fix in #1178

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

6 participants