Copy Change of specific files use Github Action - shell

I need to commit all changes in the repo to another repo. I was write this script but that did not change all the specific files I need will be changed only one file.
Anyone can help me to correct my script
- name: Copy/Create file
run: |
FILE=./project1/test.php
FILE2=./project1/test2.php
if [ -f "$FILE" ];
then
echo "Copying $FILE"
cp -R ./project1/test1.php ./project2
elif [ -f "$FILE2" ];
then
echo "Copying $FILES"
cp -R ./main-project/test2.php ./project2
fi
- name: Push change
run: |
cd ./project2
git add .
git config user.name "username"
git config user.email “useremail”
git checkout -b new-branch
git commit -am "Commit Change"
git push --set-upstream origin new-branch

Related

Remove git files/directories older than x days via GitHub Action

We use a gh-pages branch in our repository to host a static website and frequently commit new information to this branch. Those files often get stale, as we push to a subdirectory per feature branch in the same repository.
The directory structure in my gh-pages branch is similar to the following:
.
|-- README.md
|-- JIRA-1234-feature
| `-- graph
|-- JIRA-4567-bugfix
| `-- graph
|-- JIRA-7890-branch-name
| `-- testing
I want to remove directories via a GitHub actions for which the last update was more than 5 days ago.
I naively tried to remove them via find /path/to/files* -mtime +5 -exec rm {} ;, but the operating system obviously uses the clone date as the last modified time.
I also found
git ls-tree -r --name-only HEAD | while read filename; do
echo "$(git log -1 --format="%ad" --date="short" -- $filename) $filename"
done
which prints the last git update and the file name like this:
2023-01-12 JIRA-1234-test/index.html
2023-01-12 JIRA-1234-test/static/test.css
I don't know how to trigger file removal commands from this list, though.
How would I have to modify the following action to remove the old files?
name: Prune GH Pages branch
on:
workflow_dispatch:
jobs:
upload:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout#v3
with:
ref: gh-pages
- name: Cleanup
run: |
# TODO: REMOVE FILES HERE
git ls-tree -r --name-only HEAD | while read filename; do
echo "$(git log -1 --format="%ad" --date="short" -- $filename) $filename"
done
- name: Commit & Push
run: |
if [ $(git status --porcelain | wc -l) -eq "0" ]; then
echo "git repo is clean."
else
git add -A
git commit -m "branch cleanup"
git push
fi
Unfortunately, I didn't find a way to make a nice one-liner for the requirement. We need the following bash script. I have commented all the important steps.
#!/bin/bash
# Validate if $1 is a positive number days
[[ $1 != +([[:digit:]]) ]] &&
echo "$1: The script has to be run with positive number argument" && exit 1
# Get the X days ago timestamp
X_DAYS_AGO_TIMESTAMP=$(date -d "$1 days ago" +%s)
# Iterate over all files in the repository
for file in $(git ls-files); do
echo -n "."
# Get the timestamp of the last commit that modified this file
LAST_MODIFIED_TIMESTAMP=$(git log -1 --format="%at" -- "$file")
# If the file hasn't been modified within the last $1 days
if [ "$LAST_MODIFIED_TIMESTAMP" -lt "$X_DAYS_AGO_TIMESTAMP" ]; then
# Remove the file from the repository
echo -e "\nRemoving $file last modified at $(date -d "#$LAST_MODIFIED_TIMESTAMP")"
git rm --quiet "$file"
fi
done
# Commit the changes (if any)
if ! git diff --exit-code --quiet --staged; then
git commit -m "Remove files not modified within the last $1 days"
else
echo "No files removed"
fi
I can elaborate if something is not clear enough.

Git push to various repositories via bash script

I'm trying to create a bash script that iterates over 4 different folders (git repositories) and updates/pushes the changes for each one of them. I have the script mostly complete, except the authentication part.
Here's my current script:
#!/bin/bash
# Fetch username and password
echo "Please insert your git credentials!"
read -p 'Username: ' username
read -sp 'Password: ' password
# Check if you svn and git installed in your machine
if which svn &> /dev/null && which git &> /dev/null; then
# Store the current dir
CUR_DIR=$(pwd)
# Let the person running the script know what's going on.
echo "Pulling in latest changes for all repositories..."
for D in $CUR_DIR/*; do
if [ -d "${D}" ]; then
echo "${D}"
cd $(basename $D);
# Make sure SVN is on trunk branch and git branch is on master
SVN_BRANCH=$(svn info | grep '^URL:' | egrep -o '(tags|branches)/[^/]+|trunk' | egrep -o '[^/]+$')
GIT_BRANCH=$(git symbolic-ref --short HEAD)
if [ "$SVN_BRANCH"!="trunk" ] || [ "$GIT_BRANCH"!="master" ]; then
echo $CUR_DIR
echo "Make sure you're on SVN trunk branch and git master branch."
exit -1
fi
echo "Update SVN repository";
svn up
# Update git
git add .;
git commit -m "Update with the changes from svn trunk branch."
echo "Start pushing changes to main repository."
git push origin master
echo "Update git repository";
git pull origin master
# Update SVN
svn add .
svn commit -m "Update with changes from git master branch."
cd ..
fi
echo "Complete!"
done
else
echo "You need both svn and git CLI's installed to run this script!";
fi
As you can see, I'm already fetching the credentials in the beginning of the script, my problem is how can I use them to do the actions that need authentication, namely
git push origin master
git pull origin master
How can I build the git commands to make the authenticated request?

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

Can't Add '/path/to/file' to a parent directory scheduled for deletion

I've been attempting to use the following script to commit a wordpress plugin to the WP svn repo from my public git repository and keep getting error:
svn: E155013: Can't add '/path/to/file' to a parent directory scheduled for deletion
Whenever there is a new file, not previously known to svn, when adding files, resulting in either an aborted commit, or worse, a broken commit where it commits with missing files.
#! /bin/bash
# A modification of Dean Clatworthy's deploy script as found here: https://github.com/deanc/wordpress-plugin-git-svn
# The difference is that this script lives in the plugin's git repo & doesn't require an existing SVN repo.
# main config
PLUGINSLUG="my-plugin-slug"
CURRENTDIR=`pwd`
MAINFILE="my-plugin.php" # this should be the name of your main php file in the wordpress plugin
# git config
GITPATH="$CURRENTDIR/" # this file should be in the base of your git repository
# svn config
SVNPATH="/tmp/$PLUGINSLUG" # path to a temp SVN repo. No trailing slash required and don't add trunk.
SVNURL="http://plugins.svn.wordpress.org/my-plugin" # Remote SVN repo on wordpress.org, with no trailing slash
SVNUSER="wp_username" # your svn username
# Let's begin...
echo ".........................................."
echo
echo "Preparing to deploy wordpress plugin"
echo
echo ".........................................."
echo
# Check if subversion is installed before getting all worked up
#if [ $(dpkg-query -W -f='${Status}' subversion 2>/dev/null | grep -c "ok installed") != "1" ]
#then
# echo "You'll need to install subversion before proceeding. Exiting....";
# exit 1;
#fi
# Check version in readme.txt is the same as plugin file after translating both to unix line breaks to work around grep's failure to identify mac line breaks
NEWVERSION1=`grep "^Stable tag:" $GITPATH/readme.txt | awk -F' ' '{print $NF}'`
echo "readme.txt version: $NEWVERSION1"
NEWVERSION2=`grep "^ \* Version:" $GITPATH/$MAINFILE | awk -F' ' '{print $NF}'`
echo "$MAINFILE version: $NEWVERSION2"
if [ "$NEWVERSION1" != "$NEWVERSION2" ]; then echo "Version in readme.txt & $MAINFILE don't match. Exiting...."; exit 1; fi
echo "Versions match in readme.txt and $MAINFILE. Let's proceed..."
if git show-ref --tags --quiet --verify -- "refs/tags/$NEWVERSION1"
then
echo "Version $NEWVERSION1 already exists as git tag. Exiting....";
exit 1;
else
echo "Git version does not exist. Let's proceed..."
fi
cd $GITPATH
echo -e "Enter a commit message for this new version: \c"
read COMMITMSG
git commit -am "$COMMITMSG"
echo "Tagging new version in git"
git tag -a "$NEWVERSION1" -m "Tagging version $NEWVERSION1"
echo "Pushing latest commit to origin, with tags"
git push origin master
git push origin master --tags
echo
echo "Creating local copy of SVN repo ..."
svn co $SVNURL $SVNPATH
echo "Clearing svn repo so we can overwrite it"
svn rm $SVNPATH/trunk/*
echo "Exporting the HEAD of master from git to the trunk of SVN"
git checkout-index -a -f --prefix=$SVNPATH/trunk/
echo "Ignoring github specific files and deployment script"
svn propset svn:ignore "deploy.sh
README.md
bower_components
node_modules
.DS_Store
.gitmodules
advanced
assets
gulpfile.js
bower.json
package.json
.git
.gitignore" "$SVNPATH/trunk/"
echo "Changing directory to SVN and committing to trunk"
cd $SVNPATH/trunk/
# Add all new files that are not set to be ignored
echo "Doing the file adding"
# THIS IS WHERE ERROR OCCURS
svn status | grep -v "^.[ \t]*\..*" | grep "^?" | awk '{print $2}' | xargs svn add
echo "Committing"
svn commit --username=$SVNUSER -m "$COMMITMSG"
echo "Creating new SVN tag & committing it"
cd $SVNPATH
svn copy trunk/ tags/$NEWVERSION1/
cd $SVNPATH/tags/$NEWVERSION1
svn commit --username=$SVNUSER -m "Tagging version $NEWVERSION1"
echo "Removing temporary directory $SVNPATH"
rm -fr $SVNPATH/
echo "*** FIN ***"
Could anyone elaborate on what is causing this error and possibly recommend either a different or adapted approach?
Dean's version doesn't contain brainless svn rm $SVNPATH/trunk/*
rm $SVNPATH/trunk/* or checkout with --depth+commit with --set-depth

Resources