I have the following bash function, which searches for all files in a repository, whose filename matches a regular expression. It currently finds all commits in which a file exists. How can this be changed so it only searches among files that were edited (created, altered, or deleted) in each commit?
This was my original intention for the function. I was surprised to see the results being much broader than expected. The reason I'm trying to do this: I created a file a long time ago, and at some point between now and then, I accidentally deleted an important section from it. I want a list of all the points (commits) at which this file has changed, so I can quickly go back to the version containing the missing section, and paste it back into the current-commmit version.
:<<COMMENT
Searches all commits in the current git repository containing a file whose name matches a regular expression.
Usage: gitf <regex>
Parameter is required, and must be at least one non-whitespace character.
The original version of this function was based on the GitHub gist
- https://gist.github.com/anonymous/62d981890eccb48a99dc
written by Stack Overflow user Handyman5
- https://stackoverflow.com/users/459089/handyman5
which is based on this SO question:
- https://stackoverflow.com/questions/372506/how-can-i-search-git-branches-for-a-file-or-directory/372654#372654
The main section of this function was authored by Stack Overflow user
SwankSwashbucklers.
- https://stackoverflow.com/users/2615252/swankswashbucklers
- https://stackoverflow.com/a/28095750/2736496
Short description: Stored in GITF_DESC
COMMENT
#GITF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
GITF_DESC="gitf [searchterm]: Searches the current git repository for the file name that matches a regular expression.\n"
Body:
gitf() {
#Exit if no parameter is provided (if it's the empty string)
param=$(echo "$1" | trim)
echo "$param"
if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html
then
echo "Required parameter missing. Cancelled"; return
fi
wasFound="0";
LOC=refs/remotes/origin # to search local branches only: 'refs/heads'
ref="%(refname)"
for branch in `git for-each-ref --format="$ref" $LOC`; do
for commit in `git rev-list $branch | grep -oP ^.\{7\}`; do
found=$(git ls-tree -r --name-only $commit | grep "$param")
if [ $? -eq 0 ]; then
echo "${branch#$LOC/}: $commit:"
while read line; do
echo " $line"
done < <(echo "$found")
wasFound="1";
fi
done
done
if [ "$wasFound" -eq "0" ]; then
echo "No files in this repository match '$param'."
fi
}
Use git log --all <filename> to view the commits influencing <filename> in all branches.
If you want to see what's happened recently in your project, you can use git log . This command will output a list of the latest commits in chronological order, with the latest commit first.
Locally, you can use git log . The git log command enables you to display a list of all of the commits on your current branch. By default, the git log command presents a lot of information all at once.
By default git diff will show you any uncommitted changes since the last commit.
If you can live with a shell glob pattern rather than a full-blown regex, consider
git log -p --diff-filter=AMD --branches --tags -- "foo*bar.sh"
With -p
, you see the deltas along with the commit message, author, SHA1, etc. The --diff-filter=AMD
option selects only those commits in which the files in question were Added, Modified, or Deleted. To search remotes as well as local branches and tags, use --all
rather than --branches --tags
. Finally, note the --
that introduces path patterns, which you will want to quote to allow git to perform glob matching.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With