Git post commit and bash on windows - windows

I want to copy all the *.obj files (ignored by the git, but present in the directory) after commit to a directory.
With this script:
#!/bin/sh
pwd
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
echo logging objfiles for $branch
mkdir -p ./OBJ_$branch/
cp -u -f -r *.obj ./OBJ_$branch/
Git says after commit, that "Cannot stat *.obj"
Ia aware of different endlines and this file is saved using PSPad with linux endlines.
Thanks for any help!
pwd prints the correct directory.

Solved, the problem is this
http://www.linuxquestions.org/questions/linux-newbie-8/how-to-do-recursive-file-copy-of-directory-for-specific-files-199134/
cp evidently doesnt know how to do a recursion.

Related

I have a code that reads git log returning the error below

Error message: "fatal: your current branch 'master' does not have any commits yet"
After Making a file with this code executable
#!/usr/bin/env bash
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.."
{
cat <<- 'EOH'
EOH
echo
git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf
} > AUTHORS
The problem is that you didn't add anything, and possibly didn't even have a change to commit, so no commit was done. If you really want that first commit without any changes, you can do this:
git commit --allow-empty -m "first commit"

Git-Bash File Lookup Depending On File Type

I am trying to navigate through all existing all branches and lookup if files with a certain extension such as (.zip or .exe exist)
I tried to write a bash script to achieve this task.
for branch in $(git branch);
do
echo "I am in: $branch"
git ls-files *.exe
done
I would like to see the file path when it is detected.
You are not changing to the branch so you are always checking the last branch you checked out. Try this:
# In the repo's working directory
for branch in $(git branch -a|grep -v remotes|sed 's/\*//g'); do
echo "I am in branch: ${branch}"
git checkout ${branch}
find . -type f -name '*.md'
done
Following is how I solved my problem:
read -p "Extension to lookup [example: .zip]: " extensionType
for branch in $(git branch);
do
if [[ $branch == *"Release"* ]]; then
echo "----------------------------------"
echo ">>Navigating to: $branch"
echo ">>$branch..."
git checkout $branch
git ls-files "*$extensionType"
echo "----------------------------------"
fi
done
I hope this helps.

Automate post-"git move", making history log stick

I am facing merging of a few repositories in to one, with miscellaneous file moved around
Based on some research on SO, SO, how to merge repositories I ended up with following sketch:
user=some_user
new_superproj=new_proj # new repository, will include old repositories
hosting=bitbucket.org # gitgub etc
r1=repo1 # repo 1 to merge
r2=repo2
...
# clone to the new place. These are throw-away (!!!) directory
git clone git#${hosting}:${some_user}/${r1}.git
git clone git#${hosting}:${some_user}/${r2}.git
...
mkdir ${new_superproj} && cd ${new_superproj}
# dummy commit so we can merge
git init
dir > deleteme.txt
git add .
git commit -m "Initial dummy commit"
git rm ./deleteme.txt
git commit -m "Clean up initial file"
# repeat for all source repositories
repo=${r1}
pushd .
cd ../${repo}
# In the throw-away repository, move to the subfolder and rewrite log
git filter-branch --index-filter '
git ls-files -s |
sed "s,\t,&'"${repo}"'/," |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE
' HEAD
popd
# now bring data in to the new repository
git remote add -f ${repo} ../${repo}
git merge --allow-unrelated-histories ${repo}/master -m "Merging repo ${repo} in"
# remove remote to throw-away repo
git remote rm ${repo}
So far so good, unless we want to move files around while still preserving log. Git is sucks on move/rename and log rewrite fragment is not quite adapted, hence rewrite done uniform way, recursively for whole directory
Idea is, while files are moving we know there are no other changes in repository but renames and moves. So, how can I rewrite following part to be canonical, per file. Taken from git filter-branch, official documentation
git filter-branch --index-filter \
'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
I have hard time to understand stuff past 'sed' and how it is applied for git filter-branch
I want to run script (bash, python etc), so:
for each file in repository get moved/renamed
...
# in the loop, moved/renamed file found
old_file="..." # e.g. a/b/c/old_name.txt
new_file="..." # e.g. a/b/f/g/new_name.txt, at this point it is known, old_file and new_file is the same file
update_log_paths(old_file, new_file) # <--- this part is needed
Any ideas?
As it turned out to be, hinting from the following command Move file-by-file in git, it is as simple as (pseudocode):
move_files
cd repo_root
git add . # so changes detected as moves, vs added/deleted
repo_moves=collect_moves_data()
git reset HEAD && git checkout . && git clean -df . # undo all moves
Biggest misunderstanding I found is "git log --follow" or other, "stronger" options doesn't work for many in related SO questions:
git log --follow <file>
does not show log until moved, while unchanged, file is committed.
for each_move in repo_moves
old_file, new_file=deduct_old_new_name(each_move)
new_dir=${new_file%/*}
filter="$filter \n\
if [ -e \"${old_file}\" ]; then \n\
echo \n\
if [ ! -e \"${new_dir}\" ]; then \n\
mkdir --parents \"${new_dir}\" && echo \n\
fi \n\
mv \"${old_file}\" \"${new_file}\" \n\
fi \n\
"
git filter-branch -f --index-filter "`echo -e $filter`"
If you need to get back:
git pull # with merge
git reset --hard <hash> # get hash of your origin/master, orignin/HEAD), which will be HEAD~2, but I'd check it manually and copy/paste hash

How can I get git's `.git` path from git itself?

I am trying to write a shell script that needs to be able to find the .git folder for the current directory, correctly handling all of the following possibilities:
I might be in a bare repo, in which case the .git folder is either . or .. or ../.. or so on.
I might be in a submodule (in which I'll find a .git file that contains the path to the git folder)
$GIT_DIR might be set.
I might not be in a git repo at all
I have this:
seemsToBeGitdir() {
# Nothing special about "config --local -l" here, it's just a git
# command that errors out if the `--git-dir` argument is wrong.
git --git-dir "$1" config --local -l >/dev/null 2>/dev/null
return $?
}
gitdir() {
local cursor relpath
if [ "$GIT_DIR" ]; then
echo "$GIT_DIR"
return 0
fi
cursor="$(pwd)"
while [ -e "$cursor" ] && ! seemsToBeGitdir "$cursor"; do
# Git won't traverse mountpoints looking for .git
if mountpoint -q "$cursor"; then
return 1
fi
# We might be in a submodule
if [ -f "$cursor/.git" ]; then
# If .git is a file, its syntax is "gitdir: " followed by a
# relative path.
relpath="$(awk '/^gitdir:/{print$2}' "$cursor/.git")"
# convert the relative path to an absolute path.
cursor="$(readlink -f "$cursor/$relpath")"
continue
fi
if seemsToBeGitdir "$cursor/.git"; then
echo "$cursor/.git"
return 0
fi
cursor="$(dirname "$cursor")"
done
echo "$cursor"
}
And it works, but seems way too complicated -- clearly, git itself does this sort of calculation every time it's invoked. Is there a way to make git itself tell me where .git is?
Use git rev-parse, which has options specifically for this:
git rev-parse --git-dir
See also:
git rev-parse --absolute-git-dir
(new in Git version 2.13.0), and:
git rev-parse --show-toplevel
and:
git rev-parse --show-cdup
(note that its output is empty if you are already in the top level of the repository). View your own documentation to find out which options your Git supports; most of these have been around since Git 1.7, though.

Ignore symbolic links in .gitignore

Is it possible to tell Git to ignore symlinks ? I'm working with a mixed Linux / Windows environment and, as you know, symlinks are handled very differently between the two.
Use git version >= 1.6
Git used to treat sym-links the same as regular files, but newer git versions (>= 1.6) check if a file is beyond a symbolic link and will throw a fatal error.
e.g.:
# git init
# mkdir newdir
# touch newdir/foo
# git add newdir/foo
# git commit -m 'add foo'
# mv newdir /tmp/
# ln -s /tmp/newdir
# touch newdir/bar
# git add newdir/bar
fatal: 'newdir/bar' is beyond a symbolic link
# git add/tmp/newdir
fatal: '/tmp/newdir' is outside repository
# git --version
git version 1.7.3.4
No, it is not possible to do this globally. However, if you have lots of symlinks here is a bash script that you can use to easily add them to your repo's .gitignore file:
for f in $(git status --porcelain | grep '^??' | sed 's/^?? //'); do
test -L "$f" && echo $f >> .gitignore; # add symlinks
test -d "$f" && echo $f\* >> .gitignore; # add new directories as well
done

Resources