Using git diff to replicate changes in another directory - linux

I have multiple websites structured (simplified) as follows under a single GIT repository:
/
/site-1
/site-1/index.js
/site-1/about.js
/site-1/package.json
/site-1/node_modules(not versioned)
/site-1/package-lock.json(not versioned)
/site-2
/site-2/index.js
/site-2/about.js
/site-2/package.json
/site-2/node_modules(not versioned)
/site-2/package-lock.json(not versioned)
/site-3
/site-3/index.js
/site-3/about.js
/site-3/package.json
/site-3/node_modules(not versioned)
/site-3/package-lock.json(not versioned)
I did some amendments in /site-1/index.js, /site-1/package.json and added a file /site-1/changes.md.
The changes were done in 2 separate git commit in a feature branch called feature/carousel.
I want to apply the same changes in /site-2 and /site-3.
I've tried the following:
git format-patch master -o patches to retrieve the new diff in this feature branch with regards to master branch, but i was unable to apply the diff in /site-2 and /site-3.
diff -ruN site-1 site-2 > PatchFile1 to generate a consolidated diff, but it takes into account files that have been modified in /site-2 as well and its not a generic diff that can be applied directly to /site-3
Any idea how to achieve this?

You can use git apply with the --directory option to apply a patch to another main directory, as explained here:
https://blog.soltysiak.it/en/2017/08/how-to-use-git-patch-system-to-apply-changes-into-another-folder-structure/
First, create a patch file changes.patch based on the changes applied to directory site-1. Then you can do the following:
git apply -p1 --directory='site-2' changes.patch
git apply -p1 --directory='site-3' changes.patch
-p1 removes the site folder from the patch headers, which is the main part that differs between the different directories.
--directory='site-2' will cause the site-2 prefix to be added to each header in the patch

Related

xgettext dry run to avoid unnecessary commits in Github workflow

Is there any way to do a dry run of xgettext on source files, in order to simply check if there are any differences compared to the current .pot file?
I have set up a Github workflow that will run xgettext on source files any time a change to a source file is pushed to the repository. The result is that often the change to the source file didn't change the translation strings, so the only difference in the resulting .pot file is the Creation date, which gets updated every time xgettext is run. This makes for unnecessary commits, and triggers unnecessary webhook calls to my weblate instance which picks up on an "updated" .pot file, and winds up generating its own Pull Request with an "updated" .pot file.
If there were a way to do a dry run and first check if there are any actual differences in the strings, I could avoid unnecessary commits and PRs from polluting my repo. Any ideas?
I was able to add a filter to my Github workflow, checking whether there are any significant changes besides a simple update to the value of POT-Creation-Date in the .pot file. I added an id to the step that takes care of running xgettext, then after running xgettext I save the count of significant lines changed in the pot file to a variable that will be accessible to the next step:
- name: Update source file translation strings
id: update_pot
run: |
sudo apt-get install -y gettext
xgettext --from-code=UTF-8 --add-comments='translators:' --keyword="pgettext:1c,2" -o i18n/litcal.pot index.php
echo "::set-output name=POT_LINES_CHANGED::$(git diff -U0 | grep '^[+|-][^+|-]' | grep -Ev '^[+-]"POT-Creation-Date' | wc -l)"
Then I check against this variable before running the commit step:
- name: Push changes # push the output folder to your repo
if: ${{ steps.update_pot.outputs.POT_LINES_CHANGED > 0 }}
uses: actions-x/commit#v4
with:
# The committer's email address
email: 41898282+github-actions[bot]#users.noreply.github.com
# The committer's name
name: github-actions
# The commit message
message: regenerated i18n/litcal.pot from source files
etc.

How can I get the last merged branch name in git

How can i get the last merged branch name in git from the remote
Tried
git log --first-parent --merges -1 --oneline
But not getting the branch name
Please help
In general, you cannot.
A merge commit may have, as its commit message, text of the form merge branch foo or merge branch foo of someurl, but to read that message, you must obtain the commit from the remote. Even so, there's no guarantee that branch foo exists any more, or that the name means anything if it does exist. Merging really works by commit hash IDs, not by branch names; branch names may evanesce.
If you think you need a branch name here, you are probably doing something wrong. Branch names do make sense here in other version control systems, but in Git, depending on them is unwise.
Here is the command you need to give (change the branch name from origin/master to whichever branch you're checking merges for):
git log --merges origin/master --oneline --grep='^Merge' -1 | grep -oe "[^']*[^']" | sed -n 2p
I had quite a bit of a hard time trying to solve this issue.
I had to get this information for my CircleCi pipeline, and to solve my problem I used the GitHub cli.
Specifically the pr list command: https://cli.github.com/manual/gh_pr_list
The following command gives you all the information of the last PR you merged into main
gh pr list -s merged -B main -L 1
Then you need to manipulate the string and get only the branch name. Which is the text before "MERGED"
I took it splitting the string and taking the penultimate element.

how to use "--no-ff --no-commit" using GitPython while merging?

When i use commandline git merge with --no-ff --no-commit works fine. But using GitPython i am unable to dos.
May be i am not finding a correct documentation or forums for the below equivalent operation using GitPython.
Am i missing any ?
command line:
git merge --no-ff --no-commit "<TAG Name> or <Feature branch>"
GitPython:
print(f"Merging from tag '{input_tag}' into 'master'...")
repo = Repo(constants.git_clone_local_path)
repo.git.checkout('master')
repo.git.pull()
repo.git.merge(f'--no-ff --no-commit {input_tag}')
# repo.git.merge(f'{input_tag}', no_ff=True)
print(repo.git.status())
print('Done')
Python gives below error
cmdline: git merge --no-ff --no-commit test_tag
stderr: 'error: unknown option `no-ff --no-commit test_tag'
usage: git merge [<options>] [<commit>...]
or: git merge --abort
or: git merge --continue
-n do not show a diffstat at the end of the merge
--stat show a diffstat at the end of the merge
--summary (synonym to --stat)
--log[=<n>] add (at most <n>) entries from shortlog to merge commit message
--squash create a single commit instead of doing a merge
--commit perform a commit if the merge succeeds (default)
-e, --edit edit message before committing
--cleanup <mode> how to strip spaces and #comments from message
--ff allow fast-forward (default)
--ff-only abort if fast-forward is not possible
--rerere-autoupdate update the index with reused conflict resolution if possible
--verify-signatures verify that the named commit has a valid GPG signature
-s, --strategy <strategy>
merge strategy to use
-X, --strategy-option <option=value>
option for selected merge strategy
-m, --message <message>
merge commit message (for a non-fast-forward merge)
-F, --file <path> read message from file
-v, --verbose be more verbose
-q, --quiet be more quiet
--abort abort the current in-progress merge
--quit --abort but leave index and working tree alone
--continue continue the current in-progress merge
--allow-unrelated-histories
allow merging unrelated histories
--progress force progress reporting
-S, --gpg-sign[=<key-id>]
GPG sign commit
--overwrite-ignore update ignored files (default)
--signoff add Signed-off-by:
--verify verify commit-msg hook
This should work
git.merge('args', no_ff=True)
replace 'args' by yours arguments like your branch...
I didn't find any links in the documentation. But this code worked for me.
repo = Repo(constants.git_clone_local_path)
repo.git.merge(<source_branch>, no_ff=True, no_commit=True)

svn merge individual files. Add new file

I am trying to merge individual files between two branches . All is well except for newly added files in source branch .
how can I merge newly added files from source to target .
svn merge -c123 https://my.svn.domain/svn/foo/branches/bar/newfile.txt ./newfile.txt
svn: E200009: Merge target './newfile.txt' does not exist in the working copy
EDIT 1:
I am using svn version 1.7.19
EDIT 2: Getting this error while trying to merge a file with status "A" .
To merge individual file you should confirm the target file exist then use the command like :
$ svn merge -c 31 ^/brunchs/xxxx xxxx

How to get proper diff of merge commit in tig

if i got into tig main view, i get a nice graph of commits and merges. i'd prefer to just look at the merge commits to trunk but unlike with normal commits tig where tig shows the full diff with file contents, on merge commits it just shows a list of changed files in the diff view. How do i get tig to display the file contents diff on merge commits?
commit fb56223ec50cf659a308b3c9979c912881147689
Refs: [master], {origin/master}, {origin/HEAD}, juju-1.21-alpha1-229-gfb56223
Merge: 7e7c95d a017b5a
Author: Juju bot
AuthorDate: Mon Sep 22 01:22:03 2014 +0100
Commit: Juju bot
CommitDate: Mon Sep 22 01:22:03 2014 +0100
Merge pull request #803 from mjs/check-ssh-api-methods-are-allowed-during-upgrade
cmd/juju: ensure that API calls used by "juju ssh" are allowed during upgrades
We recently had a regression where an API call required by "juju ssh" wasn't being allowed by the API server while upgrades are in progress. "juju ssh" is one of the few commands that is supposed to work during upgrades.
The Client used by "juju ssh" is now forced into an interface and this is checked using reflection against what the API server will allow during upgrades. Effectively, the compiler helps to check that the required API methods will be allowed.
http://reviews.vapour.ws/r/64/diff/
apiserver/upgrading_root.go | 20 +++++++++++---------
cmd/juju/ssh.go | 15 +++++++++++----
cmd/juju/ssh_test.go | 24 ++++++++++++++++++++++++
3 files changed, 46 insertions(+), 13 deletions(-)
navigating to the individual files (j/k) in the view, says press 'Enter' to view file diff, but hitting enter gets "Failed to find file diff" err message. ideally i'd just be looking at the combined diff for the merge commit.
[update] i traced through tig with sysdig and it looks like its doing the following which on merge commits won't show the actual diff.
git show --encoding=UTF-8 --pretty=fuller --root --patch-with-stat --show-notes --no-color fb56223ec50cf659a308b3c9979c912881147689 --
i guess what i'm looking for on merge commits then is to parse the parents commits and then do something like the following
git diff 7e7c95d a017b5a
[update] so the diff actually isn't correct here as that diff would be between the two parents, and be more inclusive of changes then the merge itself, the best content rendering of the diff seems to be
git diff fb56223^ fb56223
Turns out this is pretty straightforward via external command integration.
I dropped this into ~/.tigrc:
bind diff 7 !git diff %(commit)^ %(commit)
and now just press 7 for the diff output i'm looking.
You have several options:
put this into your .tigrc
set diff-options = -m
you can set many options in ~/.tigrc, see also the manpage:
man tigrc
or start tig with the option -m
tig -m
Options to tig are passed to the underlying git command. More Info about this also in the manpage:
man tig

Resources