Windows custom git commands - windows

Say I want a new git command, git new, that makes a new branch that is up to date with origin/master.
Is there a way I can make this script and have it available in all repositories on Windows from powershell?
edit: To clarify I want a git script not a powershell function. The only reason I mentioned powershell is because I don't use git bash.

Create a batch file that contains the following commands:
git branch %1 origin/master
git checkout %1
Save it, let's say, as C:\Scripts\new-branch.cmd. (I never worked with PowerShell, I don't know its rules. However, it should work as well using the old Windows Command Prompt).
Test the batch file works as expected by running:
C:\Scripts\new-branch.cmd test1
It should output something along these lines:
Branch test1 set up to track remote branch master from origin by rebasing.
Switched to branch 'test1'
Your branch is up-to-date with 'origin/master'.
If you don't need the new branch to track the remote branch then you just add --no-track to the git branch command.
If everything goes well then run:
git config --global alias.new "!C:/Scripts/new-branch.cmd"
This makes the Git alias new available to your Windows profile in all repositories. If you need it only in one repository then remove --global and run the command when the current directory is in the repository where you need it.
Use it as:
git new test2

You can use a git alias which uses git checkout:
git config --global alias.new 'checkout origin/master -b'
This would then be used as git new new_branch.
(Which is equivolent to git checkout origin/master -b new_branch
See the git docs for checkout. I tried the command and it worked, but when I looked at the docs, I didn't find a syntax that exactly matched my form. (Closest is git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>])
Note: #axiac, I may have used the !git because it doesn't hurt, and I may have needed to do multiple commands to solve the problem, and didn't remove it when I was done.

Related

Automate "git merge" commit message [duplicate]

This question already has answers here:
Stop git merge from opening text editor
(3 answers)
Closed last year.
I constantly need to update my remote branch with current master. I am trying to automate this as;
#!/usr/bin/env bash
cd directory
git checkout master
git pull
git checkout <remote_branch>
git pull origin <remote_branch>
git merge master
git push
but when I merge master I am thrown into my editor where I need to :wq to be able to push. How can I replicate this :wq in my Bash script?
There are 3 ways listed below to do this and you don’t have to replicate :wqto do so.
1 - Using --no-edit
using the --no-edit option, the auto-generated message will be accepted (this is generally discouraged, see the git docs)
So after you git pull origin <remote_branch>, you can use
git merge master --no-edit
2 - Using environement variable
Older scripts may depend on the historical behaviour of not allowing the user to edit the merge log message. They will see an editor opened when they run git merge. To make it easier to adjust such scripts to the updated behaviour, the environment variable GIT_MERGE_AUTOEDIT can be set to no at the beginning of them. — git docs
Use
GIT_MERGE_AUTOEDIT=no
before the merge line
3 - Use -m to provide the message
Set the commit message to be used for the merge commit (in case one is created).
If --log is specified, a shortlog of the commits being merged will be appended to the specified message.
The git fmt-merge-msg command can be used to give a good default for automated git merge invocations. The automated message can include the branch description. — git docs
git merge master -m "Merge master"
Read more: the git merge command

difference between git --git-dir checkout and git checkout

git checkout acts differently for using option --git-dir.
Commands :
inside_gitdir$ git checkout remote/branch
outside_gitdir$ git --git-dir=/path/.git checkout remote/branch
Here command 1 works well and checking out. but the command 2 shows to move files like :
error: The following untracked working tree files would be overwritten by checkout:
someFiles
Please move or remove them before you can switch branches.
Aborting
I thought both the commands are running in same way. But,
Why am i getting this error in second command not in first ?
What is the difference of using --git-dir option ?
I ran into the same issue.
It seems to work if you do: git --git-dir=/path/.git --work-tree=/path/ checkout remote/branch

git pull -X theirs requires MERGE_MSG editing in ubuntu but not in windows

I have a bash script running on ubuntu and on windows:
git add -A
git commit -a -m "auto l"
git pull -s recursive -X theirs
git push origin
In ubuntu the second to last line causes nano editor to pop up requesting naming or editing of MERGE_MSG. Windows no such problem. EDIT WINDOWS TOO Rerunning the script 2 more times solves problem but that seems sloppy. Exists another -m 'auto' I must add during pull or what?
Check if (on Windows) you do have a pull.rebase setting set to true (as I recommend since Git 2.9)
git config pull.rebase
git config rebase.autoStash
That would means Git on Windows would rebase your local commits on top of origin/yourBranch, instead of trying to create a merge commit between origin/yourBranch and yourBranch.
But if you don't, and if that must create a merge commit, then, as noted by the OP, git pull --no-edit can can be used to accept the auto-generated message (this is generally discouraged, but here useful).

Git for Windows "No tags file" Response from "git diff" Command

Git version: 2.14.2.2
Whenever I run git diff on a repository I am greeted with the response No tags file. I have tried running the command on multiple repositories, multiple consoles (Cmd, PowerShell, MINGW64, Visual Studio Command Prompt) and all have the same response.
Strangely, the git log command also fails. Many other commands work, however, such as git status, git pull, etc. It seems to be only log and diff.
I have uninstalled Git entirely and reinstalled. Restarted my system. Tried referencing the git.exe directly (which yields the exact same response). Nothing is working and I have not seen this error anywhere else. I compared my user configs with those of a colleague and they are identical.
Some portion of the command executes properly, because if I supply two commit hashes, and I intentionally break one, the response I receive is:
It seems like another program may be hijacking the git diff command. I believe this because I'm not sure "No tags file" is even a possible Git response. Not sure what else it would be.
To make things even more confusing- my ultimate goal is to run the git diff within the context of an msbuild and it DOES EXECUTE CORRECTLY. Now, I could be satisfied with this, but I need to modify the diff command slightly, and running a full build each time is not productive, nor easy to troubleshoot. There is a task within the build script that runs an Exec command and it has no issues performing the diff. I'm also able to execute a Diff Against Current within SourceTree, which to the best of my knowledge, runs a git diff behind the scenes.
Any help would be very much appreciated.
:: Edits ::
Various commands:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
Output:
Every one of the commands above returns the same No tags file response, in all of my repos.
Cat Head:
cd .git
cat HEAD
ls -R refs
Output:
New Repo:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
Output:
git config -e:
git config --global -e:
::Edits 2::
I uninstalled all of my diffing/source control tools (SourceTree, Git, SVN, WinMerge, KDiff). Installed the portable version of Git. Opened CMD to a repo, put in full path to the git.exe portable and it still returned the No tags file response.
I also reviewed all of my path variables for: git, vim, ming, mintty and anything else that seemed suspect, but didn't find any.
I have restarted after performing all steps, and yet the problem persists.
::Edits 3::
I have a different user on my laptop, switched to that user and the git diff works properly, so clearly there is something with my main user that is conflicting. Will continue to look into my User directory for issues.
Here are the steps I'd take in this situation:
Try the following and check the response:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
Try the same with log:
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
I'm actually guessing that your refs are messed up, which means that the direct hashes might work, but the HEAD and/or master one may not.
Look into the .git/refs folder
From the main repo folder:
cd .git
cat HEAD
ls -R refs
Hopefully, HEAD is pointing to a branch, and if master is checked out, cat HEAD output should look like:
ref: refs/heads/master
Then, the ls -R refs, should show a heads folder, with files for each of your local branches (i.e. master and possibly others). You also likely have refs/remotes and refs/tags directories.
If any of these things are radically different or missing, that could be your issue...
Since you have reinstalled git, create a brand new repo and try the same commands:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
If this last one works, then git is likely working okay, but some tool you have is messing things up.
Post your config from git config -e and git config --global -e - maybe we can see something?
When googling for the "No tags file" message, the first results I get all talk about vi.
I do not understand why git would try to execute vi when running git diff or git log, could it be that your system is configured to use vi as a pager ?
# some possible places which could influence that :
echo $PAGER
echo $GIT_PAGER
git config --get core.pager
When digging in the documentation for less, I found that less can use a ctags file, to spot "the file that contains this tag".
So you can also look at the list of variables that influence the behavior of less :
# from bash :
# env will list all the defined environment variables
env
# the ones that impact 'less' should contain "LESS" in their names :
env | grep LESS

How do I execute several git commands in a batch file without terminating after the first command?

I tried to put a series of GIT commands that I always use continuously togeter as batch files so that I don't repeat myself too much. For example, I have this batch file called update_repo_branch.bat to update a local repo and synch a branch with the remote branch:
#echo off
if(%1) == () goto end
if(%2) == () goto end
cd %1
git checkout %2
git fetch origin
git merge oring/%2
:end
Good to be lazy, but what I found is that when a GIT command is finished, it seems to send an exit flag back to terminate whatever is running. Therefore, using a batch file to exectute them all in one go simply doesn't work. Any idea how to work around it?
I'm not sure if this is true for all Windows git packages, but at least some use a git.cmd script as a wrapper around the actual git executables (for example git.exe). So when you're batch file uses a git command, Windows is actually running another batch file.
Unfortunately, when one batch file invokes another, by default it 'jumps' to the invoked batch file, never to return (this is for compatibility with ancient MS-DOS command processors or something).
You can solve this problem in a couple ways:
invoke git in your batch files using the call command to run the git.cmd batch file and return back to yours:
call git checkout %2
call git fetch origin
rem etc...
invoke git in your batch file using the .exe extension explicitly to avoid the git.cmd batch file altogether. For this to work, you might need to make sure that you have your path and other environment variables set the way git.exe expects (that seems to be what git.cmd does in msysgit):
git.exe checkout %2
rem etc...
Assuming you are using msysGit as your Git client you might actually want to use Bash scripts for this. You could place a bash function in your ~/.bashrc (~ is usually your C:\Users\- see here) as follows
update_repo_branch() {
if [ $# != "2" ]; then
echo "Usage: update_repo_branch REPO BRANCH" 1>&2
return 1
fi
cd $1
git checkout $2
git fetch origin
git merge origin/$2
}
You can then run update_repo_branch myrepo cool-branch from the mysysGit shell.
Of course, this won't be accessible from cmd.exe. You will only be able to use it within the msysGit cygwin shell.
As i see from your example you're actually trying to sync your local branch 'branchname' with origin/branchname
For this you don't need any additional scripting, you just have to use git pull instead of sequence git checkout branchname; git fetch origin; git merge origin/branchname
take a look at the docs about tracking branches in git and their benefits.
generally speaking if you have a repo layout like this:
git branch -a
...
master
dev1
dev2
remotes/origin/master
remotes/origin/dev1
remotes/origin/dev2
And your dev1 and dev2 branches are tracking branches for origin/dev1 and origin/dev2 correspondingly then you just need to execute in repository:
git pull
This command will effectively sync up all you local tracking branches with remote ones.
for more see here:
Git pull docs
Git remote branches and tracking branches (Progit book)
Create a notepad file and paste the below content and save with .bat extension.
This script can be use for setting up git first time in a project.
!echo off
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin <YOUR_REPO_URL>
git push -u origin main
pause

Resources