0

I am reading this blog post https://www.nomachetejuggling.com/2011/09/12/moving-one-git-repo-into-another-as-subdirectory/, where the author uses the command mv !(old-project) old-project.

What does it do ?

My guess is that it copies all contents of old-project to the old-project subfolder except the old-project subfolder itself. How does it do that though ?

jcxz
  • 1,226
  • 2
  • 12
  • 25

1 Answers1

0

Bash performs filename expansion occording to the rules in pattern matching. The !(old-project) matches everything except old-project.

!(pattern-list)

    Matches anything except one of the given patterns. 

If old-project exists and is a directory and there are files or folders or others inside the current working directory named other then old-project: Then mv !(old-project) old-project moves all files and directories in the current working directory in the old-project folder in the current working directory.

Corner cases:

  • if old-project does not exists, mv will fail with mv: target 'old-project' is not a directory

  • if old-project exists and is not a directory (and not a symplink to a directory, etc), then mv will fail with same as above error.

  • if there are no files and no directories etc. in the current working directory except old-project, or old-project is missing too, then mv will fail with mv: cannot stat '!(old-project)': No such file or directory, as the !(old-project) will not expand.

Basically, !(old-project) expands to everything except old-project. In terminal I often just do mv * old-project and watch mv fail with the "can't move same dir to itself" error. In scripts using !(old-project) is a alternative.

Note that for !(pattern-list) to work in bash, the extglob shell option has to be enabled using the shopt builtin.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111