{"thread":{"id":"62718","subject":"File missing from git branch","startedAt":"2024-12-31T12:10:31Z","lastAt":"2025-01-03T10:56:39Z","messageCount":5,"participants":["Prasad Pandit","Junio C Hamano","Chris Torek"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"509762","messageId":"1964163554.5326830.1735643984559@mail.yahoo.com","threadId":"62718","inReplyTo":"1964163554.5326830.1735643984559.ref@mail.yahoo.com","subject":"File missing from git branch","fromName":"Prasad Pandit","fromEmail":"pjp@fedoraproject.org","sentAt":"2024-12-31T11:19:44Z","receivedAt":"2024-12-31T12:10:31Z","isPatch":false,"sender":{"key":"pjp@fedoraproject.org","avatar":null},"body":"Hi,\n\nKernel-ark -> https://gitlab.com/cki-project/kernel-ark/\n\n* I have forked the kernel-ark git repository. The forked tree is regularly updated by pulling commits from its upstream repository above. I have added/committed couple of config files under '../arch/x86/configs/' directory in the forked tree, not in the above upstream repository. Let's say\n\n   Fork was created on - day-0\n   Files were added on - day-1\n   Updates are pulled  - day-2, day-3, day-4 ... day-n\n\n* The issue is: the config files I added are visible only in the main (os-build) branch. If I create a new branch with\n\n   $ git branch new-branch <commit-hash/merge-hash/commit-tag/>\n\nThose config files are not visible/accessible under '../arch/x86/configs' directory.\n\n   Note => Files are added and branches are created on the same forked tree.\n\n* Generally committed local changes are visible across local branches, right? Is there a way to see/access those locally added files across local branches?\n\n* Is there a different way to do this?\n\nThank you.\n---\n  -Prasad\n"},{"id":"509770","messageId":"xmqq1pxmxyoo.fsf@gitster.g","threadId":"62718","inReplyTo":"1964163554.5326830.1735643984559@mail.yahoo.com","subject":"Re: File missing from git branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-01-01T16:53:59Z","receivedAt":"2025-01-01T16:54:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Prasad Pandit <pjp@fedoraproject.org> writes:\n\n> * Generally committed local changes are visible across local\n> branches, right? Is there a way to see/access those locally added\n> files across local branches?\n\nNot at all.\n\nIn fact, the contents on branch A is unmolested by the act of\ncommitting changes on branch B.  They are independent lines of\ndevelopment.  Otherwise your version control system is broken.\n\nUntil you decide to consolidate the change you made on branch A\ninto branch B, that is.  People call that operation \"merging branch\nA to branch B\".\n\n"},{"id":"509789","messageId":"2075804114.5670956.1735812672910@mail.yahoo.com","threadId":"62718","inReplyTo":"xmqq1pxmxyoo.fsf@gitster.g","subject":"Re: File missing from git branch","fromName":"Prasad Pandit","fromEmail":"pjp@fedoraproject.org","sentAt":"2025-01-02T10:11:12Z","receivedAt":"2025-01-02T10:11:25Z","isPatch":false,"sender":{"key":"pjp@fedoraproject.org","avatar":null},"body":"On Wednesday 1 January, 2025 at 10:24:08 pm IST, Junio C Hamano <gitster@pobox.com> wrote: \n>> * Generally committed local changes are visible across local branches, right?\n>\n>Not at all.\n>\n>In fact, the contents on branch A is unmolested by the act of\n>committing changes on branch B.  They are independent lines of\n>development.  Otherwise your version control system is broken.\n>\n\n* Sorry, my question was wrong. Let's say\n\n    day-0:\n      - Fork is created\n    day-1:\n      - upstream commits pulled into 'main' branch\n      - new files are committed into 'main' branch\n    day-2:\n      - upstream commits pulled into 'main' branch \n      - 'new-branch-1' created from 'main' branch\n    day-3:\n      - upstream commits pulled into 'main' branch\n      - 'new-branch-2' created from 'main' branch\n    ...\n    day-n\n      - upstream commits pulled into 'main' branch\n      - 'new-branch-n' created from 'main' branch\n\n* Generally committed local changes are visible across _new_ branches created from the local branch, right? ie. 'new-branch-1', 'new-branch-2', 'new-branch-n' all created from the 'main' branch, should have the files which were committed into 'main' branch on day-1, right? That is not happening.\n\n\nThank you.\n---\n  -Prasad\n"},{"id":"509791","messageId":"CAPx1GvdmrTn0x-F8yOoGrSrhXPN6At54svch=Wf=9rcz9Ri=7Q@mail.gmail.com","threadId":"62718","inReplyTo":"2075804114.5670956.1735812672910@mail.yahoo.com","subject":"Re: File missing from git branch","fromName":"Chris Torek","fromEmail":"chris.torek@gmail.com","sentAt":"2025-01-02T11:40:10Z","receivedAt":"2025-01-02T11:40:24Z","isPatch":false,"sender":{"key":"chris.torek@gmail.com","avatar":"https://avatars.githubusercontent.com/u/16826774?v=4"},"body":"On Thu, Jan 2, 2025 at 2:11 AM Prasad Pandit <pjp@fedoraproject.org> wrote:\n> * Generally committed local changes are visible across _new_ branches created from the local branch, right?\n\nThe answer here is both no and yes. [1]\n\nYour issue here lies in a misunderstanding of how Git (mis?)uses\nthe word \"branch\".\n\n ** branches **\n\nIn some other version control system, a branch is a very real,\nconcrete thing.  Creating a branch makes something permanent.\nNew commits, once made, are on *that* branch, and those commits\nare *only* that branch.\n\nGit is different.  A branch is -- depending on your point of\nview -- simply a *temporary name* for *one particular commit*.\nFrom another point of view, it is *that commit and every\ncommit reachable by working backwards from that commit's\nhistory*.\n\nI find that to really get people to understand this, it helps\nto start them out by having them forget about the word \"branch\"\nentirely.  They should instead think of commits -- which in\nGit, are found by their big ugly hash IDs -- as the unit of\nstorage in Git.  (This is *mostly* accurate, though we can get\npicky about other units of storage, but let's not do that here.)\nSo given a hash ID like 0f2ec7a4eeeec3045d7680e98f958740cd29bd77\n-- which is too big and ugly for people to deal with, but we\ncan shorten it to say 0f2ec7a4eee -- we've found one specific\ncommit, assuming it exists.  That commit contains a complete\nsnapshot of every file that Git \"knew about\" at the time you\n(or whoever) made that commit.  That's most of what most people\ncare about.\n\nBut that commit also contains some metadata: information such\nas the name and email address of the person who made the commit,\nand some date-and-time stamps, and so forth.  One of these\nmetadata items is a list of raw hash IDs of *previous* commits,\nusually exactly one entry long.  We call that hash ID the\nparent, or parents if it's longer than one entry, of the\ncommit.\n\nThe way Git stores \"history\" is precisely through these parent\nIDs.  That is, given one commit ID like 0f2ec7a4eee, Git can\nfind *that* commit.  But that commit tells which commit comes\nbefore it: 114193fd391, for instance.  Git can then find *that*\ncommit, which has another parent, which Git can find, which\nhas yet another parent, and so on.  By working backwards, one\ncommit at a time, Git finds the history of the repository.\n\nAnd *now* it's time to consider the word \"branch\".  This word\nhas two meanings: it means both 0f2ec7a4eee, the *last* commit\non the branch, and also 0f2ec7a4eee, plus 114193fd391, plus\nwhatever comes before that, plus everything all the way back\nin time to the very first commit ever.  So if this is \"br-1\",\nthen \"br-1\" means both \"0f2ec7a4eee\" and \"everything leading up\nto 0f2ec7a4eee\".  Which meaning gets used depends on context.\n\nBut there's another funny thing here.  When you're on \"br-1\"\nand you make a *new* commit, two things happen:\n\n 1. The new commit gets 0f2ec7a4eee as its list-of-previous\n    commit hash IDs.  That means whatever hash ID the new\n    commit has -- let's say a5678xxx... -- Git will be able to\n    work backwards to 0f2ec7a4eee and 114193fd391 and so on.\n\n2. The branch name, \"br-1\", is rewritten to mean a5678xxx.\n\nNo *existing* commit changes at all.  In fact, it's impossible\nto change a commit.  When you use \"git commit --amend\", you're\nparticipating in a lie (a useful little lie to be sure, but a\nlie): you don't change the existing commit, you just make a new\nand improved commit, whose parent is the same as the parent of\nthe current commit.  The current commit then gets shoved out\nof the way so that the new commit links to the current commit's\nparent, instead of the current commit itself.  Graphically,\nGit might replace this:\n\n     ... <- 114193fd391 <- 0f2ec7a4eee   <-- br-1\n\nwith this:\n\n                        0f2ec7a4eee  [lost / abandoned]\n                       /\n     ... <- 114193fd391 <- b0123456789   <-- br-1\n\nIf there's any *other* way to find 0f2ec7a4eee, however, well,\nit's still there, still holding (forever) all the files that\nit holds.\n\nAnyway, once you grasp this, it becomes possible to understand\nwhat happens with files when you make commits.  But now we have\nto dive into another aspect of Git.\n\n ** your working tree **\nThe files stored under a commit's hash ID are permanent and\nunchanging.  This is just what we want for revision control: we\n*want* to get the old files back, even if there are mistakes in\nthem.  But it's not what we want to do *new work*: we need to be\nable to rewrite files to correct mistakes and/or add new stuff.\n\nTo enable this, Git will \"check out\" a commit by copying, from\nthe permanent store, the contents of all the committed files.\nThese copies to into your \"working tree\" or \"work-tree\", and\nhere they take the form of ordinary files, which you can modify\nto your heart's content.\n\nIn other version control systems, that's the end of the story\nbecause you make new commits from your working tree.  Git again\ndiffers here, as it has a thing it calls the \"index\" or \"staging\narea\", but we won't get into these details here other than to\nmention that \"git add\" is mostly necessary.  You \"git add\" any\nupdates and then run \"git commit\" and Git makes a new commit:\n\n     ... <- 114193fd391 <- 0f2ec7a4eee <- a1234567890 <-- br-1\n\nIf you added a totally-new file to commit a1234567890, well,\nit's there in that commit.  If you check out that commit,\nthat file comes out into your working tree.  If you make\na new branch name *now*, well, let's draw that:\n\n     ... <- 114193fd391 <- 0f2ec7a4eee <- a1234567890 <-- br-1\n                                                     \\\n                                                      `- br-2\n\nYour new branch name *also identifies the new commit* by its\nhash ID, so it will contain the new file.  But suppose you make\nthe new branch name *before* this point?  That is, you have:\n\n     ... <- 114193fd391 <- 0f2ec7a4eee <-- br-1\n                                      \\\n                                       `- br-2\n\nIf you now make a new commit while \"on\" branch br-1, you get:\n\n\n     ... <- 114193fd391 <- 0f2ec7a4eee <- a1234567890 <-- br-1\n                                      \\\n                                       `- br-2\n\nThe name br-2 still identifies commit 0f2ec7a4eee, which does\nnot have the new file in it.\n\nTo make things still-more-confusing, if you create new files in\nyour working tree, but *do not* commit them, Git doesn't \"know\nabout\" the files and does not store them in the commits.  (This\nis where \"git add\" comes in again: if you didn't use it, Git\ntreats this as an \"untracked file\".)  Any such file just hangs\naround in your working tree: Git neither modifies nor removes\nthe untracked file.[2]\n\n ** that's why this is a bit messy **\n\nGiven the dual meaning of the word \"branch\" and the fact that\nwe don't know whether you meant one specific commit hash ID,\nor some other specific commit hash ID, or a chain of commits\nending in a specific hash ID, we can't really say what \"should\"\nhappen.  But you can find out by use of this principle.  Use\n\n    git rev-parse main\n\nto find out which commit hash ID \"main\" means right now, and use\nsimilar \"git rev-parse\" commands to find out which specific commit\nhash IDs other names mean right now.  Or: use \"git log --graph\n--decorate --oneline --branches\" to help you visualize the\nchain(s) of commit(s) reachable by starting at any particular\nbranch label and working backwards.\n\n  ** footnotes **\n\n[1]: https://www.reddit.com/r/lotr/comments/1608zdc/question_on_advices_from_elves/\n\n[2] There's an exception to this rule.  Suppose some historical\ncommit has a file with the same name as some existing untracked\nfile, and you ask Git to check out the historical commit.  Git\nmust replace the untracked file with the historically-tracked file\nin that old commit.  If you then switch *back* to the newest\ncommit, in which the file doesn't exist, Git has to remove the\nhistorical-commit-copy that it copied out to the working tree,\nwhich in turn destroyed the unsaved work that was hanging around\nas an untracked file.  Git has a number of precautions against\nthis kind of clobbering unsaved work, but there are some corner\ncases here that are problematic.  If you need to work with a\nhistorical commit *and* a more recent commit that might have files\nwith colliding names, consider using \"git worktree\" to make a\nplace to examine the historical commits.\n\nChris\n"},{"id":"509834","messageId":"394850972.5946685.1735899970546@mail.yahoo.com","threadId":"62718","inReplyTo":"CAPx1GvdmrTn0x-F8yOoGrSrhXPN6At54svch=Wf=9rcz9Ri=7Q@mail.gmail.com","subject":"Re: File missing from git branch","fromName":"Prasad Pandit","fromEmail":"pjp@fedoraproject.org","sentAt":"2025-01-03T10:26:10Z","receivedAt":"2025-01-03T10:56:39Z","isPatch":false,"sender":{"key":"pjp@fedoraproject.org","avatar":null},"body":"Hello Chris,\n\n* Thank you for the elaborate reply, I appreciate it.\n\nOn Thursday 2 January, 2025 at 05:10:26 pm IST, Chris Torek <chris.torek@gmail.com> wrote: \n>Git is different.  A branch is -- depending on your point of\n>view -- simply a *temporary name* for *one particular commit*.\n>From another point of view, it is *that commit and every\n>commit reachable by working backwards from that commit's\n>history*.\n>\n...\n>One of these metadata items is a list of raw hash IDs of\n>*previous* commits, usually exactly one entry long.\n>We call that hash ID the parent, or parents if it's\n>longer than one entry, of the commit.\n\n* The parent-child connection between commits is fairly convoluted and unintuitive to understand. Especially when user does not even see the parent of non-merge commits easily. For merge commits git-log(1) shows parents.\n\n* In my case what seems to happen is, the commits pulled from upstream repository come with their own parent commits and my local commits in the 'main' branch are not merged with them OR those pulled commits are not linked with the local commits history. Something like say\n\n   main-branch -> uc1 ... ucN    <= forked and upstream repository are same.\n\nWe add local commits to it\n\n   main-branch -> lc1 -> lc2 -> uc1 ... ucN\n\nHere lc1 and lc2 are local commits and uc1 onward are upstream commits. After $ git pull from upstream repository maybe it changes to\n\n                                     lc1 -> lc2\n                                    /          \\\n   main-branch -> uc1 -> uc2 -> [mc] ->  -  -  -> uc3 ... ucN  (<= earlier uc1 becomes uc3 here)\n\n* I wonder if there's a way to merge those histories with git pull(1) as\n\n   main-branch -> uc1 -> uc2 -> lc1 -> lc2 -> uc3 ... ucN\n\nAnd whether that wouldn't create new issues of it's own. I guess the diversion comes because of the merge commits '[mc]', which essentially creates two paths to traverse history. And as the number of merge commits '[mc]' increase, number of paths also increase.\n\n\nThank you.\n---\n  -Prasad\n"}]}