3

I want to automatically copy files in a specific directory and stage the files once the user types in git commit.

I tried the pre-commit hook did the copying stuff and added git add .

However the stages don't affect the commit itself, I get the message, there is nothing to commit.

Is there a way to run a script, when the user runs git add so a staging hook?

12
  • pre-commit is executed when you are doing a git commit. See this discussion, which seems to cover your case. Commented Jun 11, 2021 at 10:59
  • Question is: Why? What is reasoning behind this requirement? Commented Jun 11, 2021 at 11:16
  • @MarekR A bit special, but I have locally folder A and folder B. folder A ist the original workspace, folder B ist the new workspace. I want to develop on folder B and once I commit, I only want to commit the changes between folder A and B. So I copy the diff between them to a special folder and only this should be comitted Commented Jun 11, 2021 at 11:19
  • Looks like you do not understood what is git for and what is standard workflow with it. You should not have folders A and B. There should be only one which content is tracked by git. To try new implementation just create a branch and do commits to that branch. Do not introduce new folder for that! When you decide that experiment was successful you just merge experimental branch to main branch. Commented Jun 11, 2021 at 11:24
  • @MarekR dont mind, I exactly do know what GIt is for, how it works. It's a special case we have in one use case. I try to explain in short: Folder A is an angular application in a specific version we get from an external source. We create our own version of it but still depend on the original version as a dependency which we need to upgrade. So when there's a new version, I just pull it in Folder A and still only have my changes to it in my repository. Which is much more maintainable. Commented Jun 11, 2021 at 11:28

3 Answers 3

2

Unfortunately there are no hook for git add action, but only the listed (client) hooks in the official documentation at https://git-scm.com/book/it/v2/Customizing-Git-Git-Hooks :

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypatch
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push
Sign up to request clarification or add additional context in comments.

Comments

1

When you run git commit, Git is prepared to commit the files that are in Git's index. It is not going to commit the files that are in your working tree.

When you run git add, Git copies a working-tree file into Git's index. This ejects the old copy (if there was an old copy) and puts in the new one instead. The files that are in Git's index are in a special form, suitable for storing in a commit: these are compressed and—importantly since Git stores every file in every commit—pre-de-duplicated, so that if this copy of this file matches any copy of any file in any existing commit, it's already de-duplicated. (This means that the files that are in Git's index are useless to you. That's why you have a usable version of the same file in your working tree—at least, up until you change it.)

Now, if you run git add from a pre-commit hook, this can work, sometimes. But sometimes, there's more than one index. When there is more than one index—and it's hard for you, in a pre-commit hook, to detect this case—running git add is not going to do any good: it may affect the next index, or may affect a temporary index that will be thrown away. In any case, the result will be bad.

What this means is that unless you are steeped in the deeper magic of Git and can detect the special index cases, you should never use git add in a pre-commit hook. If you wish to run git add before committing, do that: run git add, then run git commit.

You could, for instance, write a script that does whatever you need done, then runs git add, then runs git commit. Run this script instead of git commit. That would be a much safer way to achieve what you are trying to achieve.

As Marek R suggested in a comment, this really does look like a case of an XY problem. As LeGEC answered and I suggested above, using a script seems like the way to solve the real problem.

Comments

1

From your comments : I have the feeling that you are doing something by hand (combining changes from two sources) for which git was specifically designed (git merge has already a whole lot of features).

For example : I wouldn't consider re-implementing file renames detection, or diff reconciliation. It would certainly have more bugs and be way less tested than git builtin features.

Do consider storing the two versions of that app in two branches of the same repo, and combine them using git merge.


It looks like you simply want to run a script :

./update-vendor-files.sh 

That script would use git, but, correct me if I'm wrong, I think it wouldn't be that cumbersome for a developer to know that he should run this specific action when he needs to, rather than trying to automatically trigger it on any git add or git commit action.

If you want a more gity way to call that script :

  • name it git-update-vendor-files,
  • place it on your PATH,

you can now run :

git update-vendor-files 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.