mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
feat: add rename-file command (#1149)
This commit is contained in:
parent
e1a4e7195d
commit
c32869de37
1
AUTHORS
1
AUTHORS
|
|
@ -270,6 +270,7 @@ Patches and Suggestions
|
|||
- sgleizes
|
||||
- tfendin
|
||||
- tiemonl
|
||||
- Zachary Miller
|
||||
- zentarul
|
||||
- zeroDivisible
|
||||
- zhiyanfoo
|
||||
|
|
|
|||
15
Commands.md
15
Commands.md
|
|
@ -52,6 +52,7 @@
|
|||
- [`git rebase-patch`](#git-rebase-patch)
|
||||
- [`git release`](#git-release)
|
||||
- [`git rename-branch`](#git-rename-branch)
|
||||
- [`git rename-file`](#git-rename-file)
|
||||
- [`git rename-tag`](#git-rename-tag)
|
||||
- [`git rename-remote`](#git-rename-remote)
|
||||
- [`git repl`](#git-repl)
|
||||
|
|
@ -559,6 +560,20 @@ $ git rename-branch old-name new-name
|
|||
$ git rename-branch new-name
|
||||
```
|
||||
|
||||
## git rename-file
|
||||
|
||||
Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
||||
It combines the functionality of the `mv` command and `git mv`. This is particularly useful for renaming files or directories
|
||||
to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
||||
|
||||
```bash
|
||||
# Rename a file
|
||||
git rename-file old_filename new_filename
|
||||
|
||||
# Rename a directory
|
||||
git rename-file old_directory new_directory
|
||||
```
|
||||
|
||||
## git rename-tag
|
||||
|
||||
Rename a tag (locally and remotely).
|
||||
|
|
|
|||
101
bin/git-rename-file
Executable file
101
bin/git-rename-file
Executable file
|
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Usage function
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: git rename-file [OPTIONS] <source> <destination>
|
||||
|
||||
Description:
|
||||
Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
||||
It combines the functionality of the "mv" command and "git mv". This is particularly useful for renaming files or directories
|
||||
to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message and exit.
|
||||
|
||||
Examples:
|
||||
git rename-file old_filename new_filename
|
||||
git rename-file old_directory new_directory
|
||||
EOF
|
||||
}
|
||||
|
||||
# Check for help option
|
||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check for correct number of arguments
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Error: Incorrect number of arguments."
|
||||
echo ""
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign variables
|
||||
SOURCE="$1"
|
||||
DESTINATION="$2"
|
||||
TEMP_NAME="${SOURCE}.temp"
|
||||
|
||||
# Function to check if a file or directory exists in a case-sensitive manner
|
||||
check_case_sensitive_exists() {
|
||||
local path="$1"
|
||||
local dir
|
||||
local base
|
||||
|
||||
dir=$(dirname "$path")
|
||||
base=$(basename "$path")
|
||||
|
||||
if [ -e "$dir" ]; then
|
||||
if (cd "$dir" && find . -maxdepth 1 -name "$base" | grep -q "$base"); then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if source exists and is under version control
|
||||
if ! check_case_sensitive_exists "$SOURCE"; then
|
||||
echo "Error: Source '$SOURCE' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git ls-files --error-unmatch "$SOURCE" > /dev/null 2>&1; then
|
||||
echo "Error: Source '$SOURCE' is not under version control. If file or directory is new, it must at least be staged."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if destination already exists
|
||||
if check_case_sensitive_exists "$DESTINATION"; then
|
||||
echo "Error: Destination '$DESTINATION' already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the destination directory exists
|
||||
DEST_DIR=$(dirname "$DESTINATION")
|
||||
if ! check_case_sensitive_exists "$DEST_DIR"; then
|
||||
echo "Error: Destination directory '$DEST_DIR' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create a rollback function
|
||||
rollback() {
|
||||
echo "Rolling back changes..."
|
||||
if [ -e "$TEMP_NAME" ]; then
|
||||
git mv -f "$TEMP_NAME" "$SOURCE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Trap errors to trigger rollback
|
||||
trap 'rollback' ERR
|
||||
|
||||
# Move the file to a temporary name within the Git repository
|
||||
git mv "$SOURCE" "$TEMP_NAME"
|
||||
|
||||
# Move the temporary file to the desired destination
|
||||
git mv "$TEMP_NAME" "$DESTINATION"
|
||||
|
||||
echo "Successfully renamed '$SOURCE' to '$DESTINATION'."
|
||||
|
|
@ -189,3 +189,7 @@ _git_browse(){
|
|||
_git_browse_ci(){
|
||||
__git_complete_remote_or_refspec
|
||||
}
|
||||
|
||||
_git_rename_file() {
|
||||
__gitcomp "-h --help"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,6 +316,14 @@ _git-release() {
|
|||
'--[The arguments listed after "--" separator will be passed to pre/post-release hook.]'
|
||||
}
|
||||
|
||||
_git-rename-file() {
|
||||
_arguments -C \
|
||||
'-h[show usage information]' \
|
||||
'--help[show usage information]' \
|
||||
'1:source:__git_files' \
|
||||
'2:destination:__git_files'
|
||||
}
|
||||
|
||||
_git-squash() {
|
||||
_arguments '--squash-msg[commit with the squashed commit messages]'
|
||||
_arguments \
|
||||
|
|
@ -411,6 +419,7 @@ zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
|||
refactor:'create refactor branch' \
|
||||
release:'commit, tag and push changes to the repository' \
|
||||
rename-branch:'rename a branch' \
|
||||
rename-file:'rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity' \
|
||||
rename-tag:'rename a tag' \
|
||||
rename-remote:'rename a remote' \
|
||||
repl:'git read-eval-print-loop' \
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ set __fish_git_extras_commands \
|
|||
"rebase-patch:Rebases a patch" \
|
||||
"release:Commit, tag and push changes to the repository" \
|
||||
"rename-branch:rename local branch and push to remote" \
|
||||
"rename-file:rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity" \
|
||||
"rename-remote:Rename a remote" \
|
||||
"rename-tag:Rename a tag" \
|
||||
"repl:git read-eval-print-loop" \
|
||||
|
|
@ -180,6 +181,8 @@ complete -c git -n '__fish_git_using_command merge-into' -l ff-only -d 'merge on
|
|||
complete -c git -x -n '__fish_git_using_command merge-into' -a '(__fish_git_branches)'
|
||||
# missing
|
||||
complete -c git -x -n '__fish_git_using_command missing' -a '(__fish_git_branches)'
|
||||
# rename-file
|
||||
complete -c git -f -n '__fish_git_using_command rename-file' -s h -l help -d 'Show usage information'
|
||||
# squash
|
||||
complete -c git -x -n '__fish_git_using_command squash' -a '(__fish_git_branches)'
|
||||
complete -c git -x -n '__fish_git_using_command squash' -l squash-msg -d 'commit with the squashed commit messages'
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ git-extras(1) -- Awesome GIT utilities
|
|||
- **git-rebase-patch(1)** Rebases a patch
|
||||
- **git-release(1)** Commit, tag and push changes to the repository
|
||||
- **git-rename-branch(1)** rename local branch and push to remote
|
||||
- **git-rename-file(1)** CRename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
||||
- **git-rename-remote(1)** Rename a remote
|
||||
- **git-rename-tag(1)** Rename a tag
|
||||
- **git-repl(1)** git read-eval-print-loop
|
||||
|
|
|
|||
30
man/git-rename-file.1
Normal file
30
man/git-rename-file.1
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
.\" generated with Ronn-NG/v0.8.0
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.8.0
|
||||
.TH "GIT\-RENAME\-FILE" "1" "July 2024" "" "Git Extras"
|
||||
.SH "NAME"
|
||||
\fBgit\-rename\-file\fR \- Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
||||
.SH "SYNOPSIS"
|
||||
\fBgit\-rename\-file\fR [OPTIONS] <source> <destination>
|
||||
.SH "DESCRIPTION"
|
||||
The \fBgit\-rename\-file\fR command renames a file or directory and ensures Git recognizes the change, regardless of filesystem case-sensitivity. It combines the functionality of the \fBmv\fR command and \fBgit mv\fR.
|
||||
This is particularly useful for renaming files or directories to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
||||
.SH "OPTIONS"
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
.RS
|
||||
Show usage information.
|
||||
.RE
|
||||
.SH "EXAMPLES"
|
||||
Rename a file:
|
||||
.RS
|
||||
\fBgit\-rename\-file old_filename new_filename\fR
|
||||
.RE
|
||||
Rename a directory:
|
||||
.RS
|
||||
\fBgit\-rename\-file old_directory new_directory\fR
|
||||
.RE
|
||||
.SH "AUTHOR"
|
||||
Written by Zachary Miller <\fI\%codebyzach@gmail.com\fR>
|
||||
.SH "REPORTING BUGS"
|
||||
<\fI\%https://github.com/tj/git-extras/issues\fR>
|
||||
.SH "SEE ALSO"
|
||||
<\fI\%https://github.com/tj/git-extras\fR>
|
||||
106
man/git-rename-file.html
Normal file
106
man/git-rename-file.html
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='content-type' content='text/html;charset=utf8'>
|
||||
<meta name='generator' content='Ronn-NG/v0.8.0 (http://github.com/apjanke/ronn-ng/tree/0.8.0)'>
|
||||
<title>git-rename-file(1) - Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.</title>
|
||||
<style type='text/css' media='all'>
|
||||
/* style: man */
|
||||
body#manpage {margin:0}
|
||||
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
||||
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
||||
.mp h2 {margin:10px 0 0 0}
|
||||
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
||||
.mp h3 {margin:0 0 0 4ex}
|
||||
.mp dt {margin:0;clear:left}
|
||||
.mp dt.flush {float:left;width:8ex}
|
||||
.mp dd {margin:0 0 0 9ex}
|
||||
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
||||
.mp pre {margin-bottom:20px}
|
||||
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
||||
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
||||
.mp img {display:block;margin:auto}
|
||||
.mp h1.man-title {display:none}
|
||||
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
||||
.mp h2 {font-size:16px;line-height:1.25}
|
||||
.mp h1 {font-size:20px;line-height:2}
|
||||
.mp {text-align:justify;background:#fff}
|
||||
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
||||
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
||||
.mp u {text-decoration:underline}
|
||||
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
||||
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
||||
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
||||
.mp b.man-ref {font-weight:normal;color:#434241}
|
||||
.mp pre {padding:0 4ex}
|
||||
.mp pre code {font-weight:normal;color:#434241}
|
||||
.mp h2+pre,h3+pre {padding-left:0}
|
||||
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
||||
ol.man-decor {width:100%}
|
||||
ol.man-decor li.tl {text-align:left}
|
||||
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
||||
ol.man-decor li.tr {text-align:right;float:right}
|
||||
</style>
|
||||
</head>
|
||||
<body id='manpage'>
|
||||
<div class='mp' id='man'>
|
||||
|
||||
<div class='man-navigation' style='display:none'>
|
||||
<a href="#NAME">NAME</a>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a>
|
||||
<a href="#OPTIONS">OPTIONS</a>
|
||||
<a href="#EXAMPLES">EXAMPLES</a>
|
||||
<a href="#AUTHOR">AUTHOR</a>
|
||||
<a href="#REPORTING-BUGS">REPORTING BUGS</a>
|
||||
<a href="#SEE-ALSO">SEE ALSO</a>
|
||||
</div>
|
||||
|
||||
<ol class='man-decor man-head man head'>
|
||||
<li class='tl'>git-rename-file(1)</li>
|
||||
<li class='tc'>Git Extras</li>
|
||||
<li class='tr'>git-rename-file(1)</li>
|
||||
</ol>
|
||||
|
||||
<h2 id="NAME">NAME</h2>
|
||||
<p class="man-name">
|
||||
<code>git-rename-file</code> - <span class="man-whatis">Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity</span>
|
||||
</p>
|
||||
|
||||
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
||||
<p><code>git-rename-file</code> [OPTIONS] <source> <destination></p>
|
||||
|
||||
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
||||
<p>The <b>git-rename-file</b> command renames a file or directory and ensures Git recognizes the change, regardless of filesystem case-sensitivity. It combines the functionality of the <b>mv</b> command and <b>git mv</b>.</p>
|
||||
<p>This is particularly useful for renaming files or directories to change only their case, which might not be detected by Git on case-insensitive filesystems.</p>
|
||||
|
||||
<h2 id="OPTIONS">OPTIONS</h2>
|
||||
<dl>
|
||||
<dt><b>-h, --help</b></dt>
|
||||
<dd>Show usage information.</dd>
|
||||
</dl>
|
||||
|
||||
<h2 id="EXAMPLES">EXAMPLES</h2>
|
||||
<p>Rename a file:</p>
|
||||
<pre><code>git-rename-file old_filename new_filename</code></pre>
|
||||
<p>Rename a directory:</p>
|
||||
<pre><code>git-rename-file old_directory new_directory</code></pre>
|
||||
|
||||
<h2 id="AUTHOR">AUTHOR</h2>
|
||||
<p>Written by <Zachary Miller> <<a href="mailto:your.email@example.com" data-bare-link="true">codebyzach@gmail.com</a>></p>
|
||||
|
||||
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
|
||||
<p><<a href="https://github.com/tj/git-extras/issues" data-bare-link="true">https://github.com/tj/git-extras/issues</a>></p>
|
||||
|
||||
<h2 id="SEE-ALSO">SEE ALSO</h2>
|
||||
<p><<a href="https://github.com/tj/git-extras" data-bare-link="true">https://github.com/tj/git-extras</a>></p>
|
||||
|
||||
<ol class='man-decor man-foot man foot'>
|
||||
<li class='tl'></li>
|
||||
<li class='tc'>July 2024</li>
|
||||
<li class='tr'>git-rename-file(1)</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
43
man/git-rename-file.md
Normal file
43
man/git-rename-file.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
git-rename-file(1) -- Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
||||
================================================
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
`git-rename-file` [OPTIONS] <source> <destination>
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
The `git-rename-file` command renames a file or directory and ensures Git recognizes the change, regardless of filesystem case-sensitivity. It combines the functionality of the `mv` command and `git mv`.
|
||||
|
||||
This is particularly useful for renaming files or directories to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
||||
|
||||
## OPTIONS
|
||||
|
||||
-h, --help
|
||||
Show usage information.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
Rename a file:
|
||||
|
||||
```sh
|
||||
git-rename-file old_filename new_filename
|
||||
```
|
||||
|
||||
Rename a directory:
|
||||
|
||||
```sh
|
||||
git-rename-file old_directory new_directory
|
||||
```
|
||||
|
||||
## AUTHOR
|
||||
|
||||
Written by Zachary Miller <<codebyzach@gmail.com>>
|
||||
|
||||
## REPORTING BUGS
|
||||
|
||||
<https://github.com/tj/git-extras/issues>
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
<https://github.com/tj/git-extras>
|
||||
|
|
@ -52,6 +52,7 @@ git-reauthor(1) git-reauthor
|
|||
git-rebase-patch(1) git-rebase-patch
|
||||
git-release(1) git-release
|
||||
git-rename-branch(1) git-rename-branch
|
||||
git-rename-file(1) git-rename-file
|
||||
git-rename-remote(1) git-rename-remote
|
||||
git-rename-tag(1) git-rename-tag
|
||||
git-repl(1) git-repl
|
||||
|
|
|
|||
Loading…
Reference in a new issue