feat: add rename-file command (#1149)
Some checks failed
ci / lint (push) Has been cancelled
ci / typo (push) Has been cancelled
ci / test (push) Has been cancelled
ci / build (macos-latest) (push) Has been cancelled
ci / build (ubuntu-latest) (push) Has been cancelled

This commit is contained in:
CodeByZach 2024-08-02 04:19:35 -04:00 committed by GitHub
parent e1a4e7195d
commit c32869de37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 314 additions and 0 deletions

View file

@ -270,6 +270,7 @@ Patches and Suggestions
- sgleizes
- tfendin
- tiemonl
- Zachary Miller
- zentarul
- zeroDivisible
- zhiyanfoo

View file

@ -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
View 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'."

View file

@ -189,3 +189,7 @@ _git_browse(){
_git_browse_ci(){
__git_complete_remote_or_refspec
}
_git_rename_file() {
__gitcomp "-h --help"
}

View file

@ -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' \

View file

@ -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'

View file

@ -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
View 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
View 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] &lt;source&gt; &lt;destination&gt;</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 &lt;Zachary Miller&gt; &lt;<a href="mailto:your.email@example.com" data-bare-link="true">codebyzach@gmail.com</a>&gt;</p>
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
<p>&lt;<a href="https://github.com/tj/git-extras/issues" data-bare-link="true">https://github.com/tj/git-extras/issues</a>&gt;</p>
<h2 id="SEE-ALSO">SEE ALSO</h2>
<p>&lt;<a href="https://github.com/tj/git-extras" data-bare-link="true">https://github.com/tj/git-extras</a>&gt;</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
View 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 &lt;<codebyzach@gmail.com>&gt;
## REPORTING BUGS
<https://github.com/tj/git-extras/issues>
## SEE ALSO
<https://github.com/tj/git-extras>

View file

@ -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