0

What I need is less than a branch, and submodule doesn't appear to be a fit.

I have a repo with three files:

  • /foo.bar
  • /foo1.bar
  • /foo2.bar

This isn't really production code. It is demonstration code.

foo.bar is a stand alone function, and I will now build a real piece of code from it in /foo3.bar.

In a perforce context, I would branch foo.bar to foo3.bar and then start working on foo3.bar. This would give me all the history of foo.bar, and allow changes to foo.bar to be integrated into foo3.bar.

Another way to say it: I need to rename foo.bar to foo3.bar. However, live in VCS land and must always retain the full commit history. Imagine further: Over the history of foo9.bar, it has been named foo.bar, foo3.bar, and a few other names before arriving at foo9.bar. How is the full history, including all commits and all renames, done?

(And then my original scenario simply retains one of the earlier files in addition to the subsequent names. For example, foo.bar is renamed to foo3.bar, but then foo3.bar persists into the future and also becomes foo9.bar.)

How do I do this in git?

Jonesome Reinstate Monica
  • 6,618
  • 11
  • 65
  • 112
  • 3
    Sounds like you want a branch. Or I'm just not understanding the relationship between `foo` and `foo3` right. – tkausl Feb 08 '22 at 01:28
  • See if this helps: https://stackoverflow.com/questions/10963878/how-do-you-fork-your-own-repository-on-github – Namandeep_Kaur Feb 08 '22 at 01:46
  • I'm thinking branch as well. Can you elaborate on this sentence: "This would give me all the history of foo.bar, and allow changes to foo.bar to be integrated into foo3.bar." An example of the history and an example of what you mean by integrating foo.bar into foo3.bar? – TTT Feb 08 '22 at 02:52
  • @TTT please see enhanced OP. Thanks! – Jonesome Reinstate Monica Feb 08 '22 at 05:29
  • Git doesn't do this. Linus Torvalds dismissed renaming with some hand-waving arguments in a mailing list long ago, and as a result, git has some hacky support for simulated renaming whereby if you do `log graph --follow`, it will sort of guess that some file `A` used to be `B`. – Kaz Feb 08 '22 at 05:33
  • @Kaz Wow, that is real, uh, bad stuff (in the world I come from). In my world, everything an engineer ever does is version tracked, and renaming is something that happens.... (and god knows losing the commit history is a never-ever). Guess I'll have to punt on the whole idea. I soooo miss perforce. – Jonesome Reinstate Monica Feb 08 '22 at 05:40
  • There is `git mv` to rename an object. But each commit in git is just a tree-like snapshot; there is no rename information. The git tooling like `git log --follow` ferrets that out. It notices: hey, the commit before this one doesn't have a `foo1.bar` but does have a `foo.bar`. I.e. files are added and removed. It then analyzes these files and can guess that they are renames. – Kaz Feb 08 '22 at 07:18

1 Answers1

0

You're looking for file identity.

Files, in Git, do not have identity. It's simply not there. Git has only commit-level identity. As Kaz notes in comments, Git will do a "best effort" attempt at rediscovering file identity after-the-fact.

Because Git assumes, by default, that files with the same name are "the same file", you can get as close as you like to file identity by ensuring that the file's name never changes. To make this work with what you're doing, consider giving the file an internal numeric ID as its true name and storing this in, e.g., a hidden directory .source/flatfile1234. Replace the user-oriented names foo3.bar with symbolic links.

Git doesn't really handle symbolic links terribly well either—they can't be merged—but now you have your file identity.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thank you! And good god, that is horrible (from a VCS/corporate IP management perspective). No one every said Git was the best... and this is an example of why. Thank you again. I always seem to be learning new things about Git internals! (Often not to my happiness!) – Jonesome Reinstate Monica Feb 08 '22 at 18:42