Making a bullet-proof Git checkout in our CD job - bash

The simplified story is that we have a site installed on multiple servers (e.g QA, Prod).
Git is set to another branch/tag for every environment, and we have deployment scripts that are generic for all environments to make things simple. The scripts are getting the desired branch/tag and then run the following commands:
GIT_CHECKOUT="${1:-develop}"
git clean --force --quiet
git fetch --all
git pull --all
git checkout $GIT_CHECKOUT
We have a few issues with that:
Since we want to support both branch and tags we use both git pull and git fetch and git pull fails on the detached head mode, that works but it throws irrelevant errors to our logs
Sometimes checkout fails because of a dirty environment (usually it happens without us knowing what caused it in the first place since no one changed files manually on those environments)
I took a look on the way Jenkins do it and it looks something like that:
> git fetch --tags --progress https://myrepo.com/repo.git +refs/heads/*:refs/remotes/origin/*
> git rev-parse origin/mytag^{commit}
> git rev-parse mytag^{commit}
> git config core.sparsecheckout
> git checkout -f hash-of-commit
> git rev-list --no-walk hash-of-commit
Finally, the questions:
Should we work only in detached head mode when deploying? It does sound like a more stable solution.
Is there a "recipe" for that task? It is a very common task, and despite that, I couldn't find any online recipe to do it with your own bash script

It makes sense that on 'detached HEAD' you get an error when trying pull... because pull uses the upstream branch to merge... if you are on detached HEAD, you won't have an upstream branch. Doing git fetch should be enough to update the remote information on the local. If you really want to do checkout and don't want to care for if you have a dirty environment or not, you might try gir reset --hard instead.
This is what I would do:
git clean --force --quiet
git fetch --all
git checkout --detach # disconnect from whatever branch I was working on
git reset --hard $GIT_CHECKOUT
The only thing is that you are not moving anything locally (no local branches are moving with the remote branches, for example).

My take would be this (untested):
GIT_CHECKOUT="${1:-develop}"
# cleanup *every* untracked file and dir
git clean --force -d -x --quiet
# undo every change to untracked files - might disturb update
git reset --hard HEAD
# now the working tree should be *pristine*
# update all tracking branches and tags
git fetch --all --tags
git checkout --detach
# delete any local branch
git for-each-ref --format="%(refname:strip=2)" refs/heads |xargs -r git branch -D
# checkout
git checkout $GIT_CHECKOUT

Related

git/visual studio

How do I create a new GitHub repository from a local branch from a cloned repo with visual studio?
Been searching and trying for 3 days but nothing works plz help
you can reveal the files in file explorer from that repository and after that takes the file without git and implement a new git repository
In terminal
$ cd PARENT-FOLDER
$ git init REPOSITORY-NAME
Initialized empty Git repository in /Users/local/repo/.git/
Creates a new folder on your computer, initialized as a Git repository
$ cd REPOSITORY-NAME
Changes the working directory
$ mkdir docs
Creates a new folder called docs
$ cd docs
$ git checkout --orphan newbranch
Creates a new branch, with no history or contents, called newbranch , and switches to the newbranch branch
$ git rm -rf .
Removes the contents from your default branch from the working directory
git add .
git commit -m ‘’
$ git remote add origin https://github.com/USERNAME/REPOSITORY.git
$ git push -u origin BRANCH
commits & pushes changes to repo

hg clone tag or branch

We are using the following command to clone repositories;
hg clone -u v1.0 \\server\abc\def my_repo
If the repository contains both a tag and branch that is named "v1.0" then the command will update to the tag revision. In this situation, how can we force the hg clone command to select the branch? We do not want to use the --branch option because some repositories may only contain the tag and not the branch.
Tried various combinations of this command (with single and double quotes) and they all reported "unknown revision"
hg clone -u branch(v1.0) \\server\abc\def my_repo
hg clone -u "branch(v1.0)" \\server\abc\def my_repo
hg clone -u 'branch(v1.0)' \\server\abc\def my_repo
Does hg clone support using revset?
Please advise :-)

git commands working on windows command line but not in Git Bash terminal

I'm working on remote repository with git commands on windows cmd and it works well, but when working with git commands in git bash terminal I get error:
Your configuration specifies to merge with the ref 'refs/heads/feature/branch-name'
from the remote, but no such ref was fetched.
How can I fix it for git bash terminal?
Check first, in your git bash session, the ouput of:
git branch -avv
git status
Make sure the name of the branch you are in matches the remote one, especially considering the case (uper/lowercase), in case it is insensitive in a CMD session, and sensitive in a bash session.
See this example.
If the list of branches show the local one is not linked to a remote tracking one, then, as I documented in "[Difference between git checkout --track origin/branch and git checkout -b branch origin/branch][2]":
git branch -u origin/branch branch
It started working when I moved to the main branch (next).
But, when i switch back to my branch this is what I get:
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> feature/branch-name
Finally found the answer here:
Why do I have to "git push --set-upstream origin <branch>"?
git push -u origin <your-local-branch-name>
So if your local branch name is coffee
git push -u origin coffee

Unable to change Visual Code repository settings

I searched a lot for solutions for it, tried many ways to reset everything to 0.
I tried to set up visual studio (Windows 10 64 bits) to work with bitbucket without success.
It never accepts my password, even when I reset it.
Tried to delete any folders that would have settings without success either.
Tried to revert it to GitHub with no success either. Deleting the repositories did not improve.
Looking for git in: C:\Program Files\Git\cmd\git.exe
Using git 2.18.0.windows.1 from C:\Program Files\Git\cmd\git.exe
> git rev-parse --show-toplevel
> git config --get commit.template
Open repository: d:\
> git fetch
> git status -z -u
> git check-ignore -z --stdin
Missing or invalid credentials.
Skip fetch commands
Missing or invalid credentials.
Skip fetch commands
remote: Unauthorized
fatal: Authentication failed for 'https://bitbucket.org/gusnd/mem/src/master/'
> git symbolic-ref --short HEAD
> git rev-parse master
fatal: ambiguous argument 'master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
> git for-each-ref --format %(refname) %(objectname) --sort -committerdate
> git remote --verbose
After unistalling git things worked fine but, if I reinstall it, I get the same issue.
Any ideas?
ok, I found a hidden .git folder on D: drive root... and other files on program data, seems to be fixed

Xcode upgrade gives "warning: push.default is unset" when doing a git push

I have been using git for some time and it was working fine on my repository. However, I upgraded to XCode 7 recently and now when I try to do a git push <branch>, I get the following error message:
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:
git config --global push.default matching
To squelch this message and adopt the new behavior now, use:
git config --global push.default simple
When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.
Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.
See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)
fatal: 'Develop_New_Car' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
I have git version 2.3.3
and running which git gave me /usr/local/bin/git
A git config --global push.default simple should be enough, but XCode7 might not be looking for the global setting in the same place ($HOME) as before.
In that case, try at least to set that config locally in the repo managed by XCode7:
cd /path/to/my/git/repo
git config push.default simple

Resources