dugite icon indicating copy to clipboard operation
dugite copied to clipboard

"git stash push" command failed with multiple specified files

Open TerryChan opened this issue 5 years ago • 2 comments

I'm using the open source project GitHub Desktop to implement some features, and the GitHub Desktop used dugite as its git core. I want to implement stash multiple specified files with the command below: git stash push --include-untracked --message 'stashmessage' -- 1.txt 2.txt 3.txt

I can execute the command in command line successfully but failed in GitHub Desktop. command line: image GitHub Desktop with dugite: image It succeed with only one specified file. I'm not sure whether it's the issue of dugite. Do you know how to resolve this issue?

TerryChan avatar Aug 06 '19 13:08 TerryChan

Hi @TerryChan I'm afraid I need more information before I can help. What Dugite API calls are you making that result in the output above? And what steps do you do before the actual stash? The more detailed reproduction scenario you can provide, the better! Thank you!

outofambit avatar Aug 06 '19 18:08 outofambit

Hi @outofambit I called the GitProcess.exec() method to execute git stash push command as below:

  let args = ['stash', 'push', '--include-untracked', '--message', message]
  if (files && files.length > 0) {
    args.push('--')
    args.push(files.join(' '))
  }

  const result = await GitProcess.exec(args, repository.path)
  if (result.exitCode === 0) {
    const output = result.stdout
    // do some things with the output
    console.log('stash dugite', output)
  } else {
    const error = result.stderr
    // error handling
    console.log('stash dugite', error)
  }

Before I call the method, there are 3 modified files in my repository, and the files parameter in the code above icnludes 3 files. And then the execution failed with 'No local changes to save'. I did further test and found:

  1. If the files include only one file, it succeed
  2. The same command with multiple files executed in command line also succeed

So the root cause is the GitProcess.exec() method cannot recognize the pathspec of mutiple files.

With further investigation, I found the GitProcess.exec() method use execFile method of child_process to execute the git command. And after I change the execFile method to add windowsVerbatimArguments option with a true value, the issue resolved, it can stash multiple files.

So I think maybe this is a bug of GitProcess.exec() method that cannot execute command correctly with pathspec of multiple files, such as git add {pathspec...}, git stash push {pathspec...}.

I verified the solution on Windows only, and didn't verify on Macos. The issue also reproduced on MacOS, and I think the solution above cannot resolve the issue on MacOS. If you have solution on MacOS, please let me know, thank you in advance.

By the way, to resolve the issue, I wrote a test code to simulate GitProcess.exec() method, you can use the code to have a fast test.

var ChildProcess = require('child_process')

var command = 'git'

let args = [
    'stash',
    'push',
    '--include-untracked',
    '--message',
    `stash message`,
    '--',
    '1.txt 2.txt 3.txt'
    // 'status'
  ]

var options = { windowsVerbatimArguments: true, cwd:'E:\\YourTestRepository' }

var child = ChildProcess.execFile(command, args, options)
child.stdout.on('data', data => {
  console.log('stdout.data', data.toString())
})

child.stderr.on('data', data => {
  console.log('stderr.data', data.toString())
})

child.on('error', err => {
  console.log('error', err.message)
})

TerryChan avatar Aug 07 '19 15:08 TerryChan