Place command resulted by a git alias to bash history - bash

The following git alias give a menu to select the remote and branch name for fetch command.
git config --global alias.fh '!git fetch $(git remote | rofi -dmenu) $(git branch | sd "^[\*]*[ ]*" ""| rofi -dmenu)'
The end result of this alias (shown by echo git fetch $(git remote | rofi -dmenu) $(git branch | sd "^[\*]*[ ]*" ""| rofi -dmenu)) is something like:
git fetch origin1 branch2
git fetch origin2 branch3
git fetch origin3 branch1
My issue is, in bash history I only get git fh when the alias is run. However, In history, I would like to have whatever was the end result of the last invocation of git fh (something like git fetch origin2 branch3).
How can I do that?

Related

How to add multilines commit messages via command line - GIT?

I create this alias on my Mac OS and my Linux, when I'm lazy to type in a commit message.
I ran PUSH it triggered
It will push to current branch with these sample commands
PUSH () {
message=$(git diff --name-only)
git commit -am "update $message"
git push origin $(git rev-parse --abbrev-ref HEAD)
git log --name-status HEAD^..HEAD
git diff HEAD^ HEAD
}
git diff --name-only
app/Http/Controllers/BabyController.php
resources/views/layouts/be/baby/scripts.blade.php
resources/views/layouts/be/baby/styles.blade.php
I would like to add a breakline \n to each line like this :
app/Http/Controllers/BabyController.php\n
resources/views/layouts/be/baby/scripts.blade.php\n
resources/views/layouts/be/baby/styles.blade.php\n
How do I do that?
If you want your commit messages to be multiline through command line you can do this:
git commit -m "first line" -m "second line" -m "third line"

Bitbucket Pipeline trying to get list of files changed compared to

I have the following bash script I use to perform linting checks in a bitbucket pipeline.
#!/bin/bash
set -e
git fetch origin master:refs/remotes/origin/master
FORK_POINT=$(git merge-base HEAD origin/master)
PY_FILES=$(git --no-pager diff --name-only HEAD $FORK_POINT | grep "\.py$")
if [ "$PY_FILES" ]; then
flake8 $PY_FILES
else
echo "No *.py files found"
exit 0
fi
This was working fine up until December 4th around 4pm UTC. After some experimenting, I have narrowed the problem down to this line
PY_FILES=$(git --no-pager diff --name-only HEAD $FORK_POINT | grep "py$"). When I remove the grep and echo $PY_FILES the script completes successfully but nothing shows up in the log. So, it appears that git --no-pager diff --name-only HEAD $FORK_POINT isn't returning anything when run by the pipeline, which I guess causes grep to error? When I run this locally it is all fine, so git --no-pager diff --name-only HEAD $FORK_POINT should definitely be returning results.
Can anyone help me find out what went wrong here, or advise me on another way I can get a list of python files changed in a branch to run flake8 on?
It looks like you simply need to debug your pipeline ; one obvious difference between your local clone and the one used by bitbucket pipeline is that you are very probably not working on the same active commit (HEAD).
Have your pipeline output what it is working with :
its active commit : git rev-parse HEAD
its version of origin/master : git rev-parse origin/master
the reuslt of git merge-base : echo $FORK_POINT
From your comments : an empty FORK_POINT could indicate that the pipeline was trigered from a commit which hasn't a common ancestor with origin/master anymore.
Check the history of the remote HEAD :
git log --graph --oneline <sha from the pipeline>
You can for example compare it to the history of origin/master :
git log --graph --oneline <sha> origin/master

PowerShell - git checkout -B without reset or alternatives?

Related to this question: git checkout -B without reset or alternatives?
I want to change branches, but create the branch if it doesn't exist. -B doesn't work, as I have un-pushed commits on the branches and don't want them to be reset.
How would you write this: git checkout branchname -- 2>/dev/null || git checkout -b branchname in powershell?
The equivalent of this shell command...
git checkout branchname -- 2>/dev/null || git checkout -b branchname
...in PowerShell would be this:
$branchname = "your-branch"
git checkout $branchname 2>&1 | Out-Null
if (-not $?) {
git checkout -b $branchname
}
It uses the $? automatic variable, to determine if the last command succeeded. Also, error stream redirection and Out-Null.
Note that in PowerShell 7 (Core), || and && are also available, called pipeline chain operators.
git checkout $branchname || git checkout -b $branchname

change directory in bash is not affecting the post-commit hook

i've made the following bash script to commit the parent repo after some change in submodule.
it's all about that the script want to cd .. to check the parent repo current branch but the problem is that the cd .. is not affecting the upcoming commands because i guess the subshell
i've tried to run
1- cd ../ && before each command
2- make alias but didn't succeed
3- run exec but the script didn't continued
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "post-commit".
commit_msg= git log -1 --pretty=%B
if [[ $(git branch | grep \* | cut -d ' ' -f2) == "int1177/next" ]]; then
cd ..
if [[ $(git branch | grep \* | cut -d ' ' -f2) == "B0/next" ]]; then
git add 6_Tests
git commit -m "bs esss"
echo "development branch B0/next has now new commit"
else
echo "development branch isn't B0/next"
fi
else
echo "current branch isn't int1177/next"
fi
Actually, this particular problem is not a bash issue, but rather a Git issue.
Why doesn't "cd" work in a shell script? is valid in general, and is a suitable answer to many other questions. But this particular post-commit hook is trying to chdir out of a submodule into its parent superproject, then make a commit within the parent superproject. That is possible. It may be a bad idea for other reasons—in general it's unwise to have Git commit hooks create commits, even in other repositories1—but in this particular case you're running into the fact that Git finds its directories through environment variables.
In particular, there's an environment variable GIT_DIR that tells Git: The .git directory containing the repository is at this path. When Git runs a Git hook, Git typically sets $GIT_DIR to . or .git. If $GIT_DIR is not set, Git will find the .git directory by means of a directory-tree search, but if $GIT_DIR is set, Git assumes that $GIT_DIR is set correctly.
The solution is to unset GIT_DIR:
unset GIT_DIR
cd ..
The rest of the sub-shell commands will run in the one-step-up directory, and now that $GIT_DIR is no longer set, Git will search the superproject's work-tree for the .git directory for the superproject.
As an aside, this:
$(git branch | grep \* | cut -d ' ' -f2)
is a clumsy way to get the name of the current branch. Use:
git rev-parse --abbrev-ref HEAD
instead, here. (The other option is git symbolic-ref --short HEAD but that fails noisily with a detached HEAD, while you probably want the quiet result to be just the word HEAD, which the rev-parse method will produce.)
1The main danger in this case is that the superproject repository is not necessarily in any shape to handle a commit right now. Edit: or, as discovered in this comment, is not even set up to be a superproject for that submodule, yet, much less to have a submodule-updating commit added.

Git check file contents across branches

I'm currently using the following two bash functions to chunk through our git repo to determine what the latest version number is on each branch. Since we have several git hooks, including post-checkout, the gitTrackAll function can take quite a while to run. Is there any way to do what I'm doing without checking out every branch, pulling it in, then running a git show?
To clarify, I'm currently checking out each branch and getting the contents of the VERSION file. This essentially tells me what the last version that was merged into that branch is. We occasionally have some branches that stagnate while the developer is working on them. This list provides us a quick way to see what's way behind.
gitTrackAll && gitBranchVersions
function gitTrackAll(){
remote='origin';
for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD| awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do
git checkout "$brname"
git branch --set-upstream-to $remote/$brname $brname;
git pull
done
git checkout master
}
function gitBranchVersions(){
line='--------------------------------------------------------------------------------'
line="$line$line"
for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
VER=$(git show "$branch":VERSION);
printf "%s %s $VER\n" $branch "${line:${#branch}}"
done
}
The resulting output looks a little like the following (branch names changed)
refs/heads/1954-branch-a ---------------------------------------------------------------------------------------------------------------------------------------- 2.9.27
refs/heads/1955-branch-b ---------------------------------------------------------------------------------------------------------------------------------------- 2.9.43
refs/heads/1965-branch-c ---------------------------------------------------------------------------------------------------------------------------------------- 2.9.32
refs/heads/1968-branch-d ---------------------------------------------------------------------------------------------------------------------------------------- 2.9.101
refs/heads/1969-branch-e ---------------------------------------------------------------------------------------------------------------------------------------- 2.9.114
refs/heads/master ----------------------------------------------------------------------------------------------------------------------------------------------- 2.9.115
I would rewrite gitTrackAll the following way without any checkout at all:
function gitTrackAll(){
remote='origin';
for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD| awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do
git branch --set-upstream-to $remote/$brname $brname;
# git fetch cannot update the current branch - use git pull
git fetch $remote $brname:$brname || git pull $remote $brname
done
}
It looks like I can read files straight from remote. Using pieces from both functions, I've come up with the following, which works perfectly for the application I need.
function gitBranchVersions(){
line='--------------------------------------------------------------------------------'
line="$line$line"
remote='origin' ;
git fetch --all --prune
for brname in `git branch -r | grep $remote | grep -v HEAD| awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do
VER=$(git show "$remote/$brname":VERSION);
printf "%s %s $VER\n" $brname "${line:${#brname}}"
done
}

Resources