LOCAL PROJECT BASIC STEPS / STATIC KEEPERS

Basic Stepsuseful gitResolving Conflicts - Package.json / Package-lock.jsonBreakdown - Expanded

Know you versions:

REACT: “^16.13.1”
NODE: 14.16.1 / NPM: 7.11.2

Do you need access to a npm private package:

Login URL: https://www.npmjs.com/login
Username: username
Email: private@packsgeemail.com
Password: PackagePassword

GIT/OPENING PROJECT::

get files from a branch and create folder:


    git clone -b nameOfRemoteBranch https://urlofgitrepo.com/with/files.git NewLocalFolder

enter folder:

cd NewLocalFolder

make a new branch for yourself + set it to track origin (upstream branch):

$ git checkout -b MyNameIsLocalBranch origin/working-on-remote-branch

  Branch MyNameIsLocalBranch set up to track remote branch working-on-remote-branch from origin.
  Switched to a new branch 'MyNameIsLocalBranch'

check your node version:

node –version

install correct node for project:

nvm install 14.16.1

2x check

node –version

install dependencies:

npm install

launch dev:

npm start

view dev site locally:
https://localhost:3000

Hack Hack

do some coding …

Ready to add / commit / push to remote?

TO REMOTE pt1: STATUS see what you have changed – provides a list:

 git status

TO REMOTE pt2: ADD add changes into git to be committed:

git add filenamefromstatuslist

(can do them one at a time or use git add .)

TO REMOTE pt3: COMMIT once you add them – commit them:

git commit -a -m “a note about what these changes are for”

TO REMOTE pt4: PULL get tip of remote even + integrate remote into local branch:

Different Named Branches Need Pulling

Pull performs a merge on the retrieved changes, you should ensure that your local work is committed before running the pull command.

Before you begin to push – you have a local branch with a different name (MyNameIsLocalBranch) than the remote (working-on-remote-branch):

In order to push your MyNameIsLocalBranch to another branch, you may need to merge the remote working-on-remote-branch branch to your current local branch MyNameIsLocalBranch.

In order to be merged, the tip of the remote branch cannot be behind the branch you are trying to push.

Before pushing, make sure to pull the changes from the remote branch and integrate them with your current local branch.



$ git pull origin working-on-remote-branch (will pull working-on-remote-branch from remote)

$ git checkout MyNameIsLocalBranch (to be sure you are on correct local branch)

$ git merge origin/working-on-remote-branch (merge remote into MyNameIsLocalBranch)

TO REMOTE pt5-FNL: PUSH

Check what you have set up

git remote show origin

1st push from local to remote

git push --set-upstream origin MyNameIsLocalBranch:working-on-remote-branch 
shorthand: git push -u origin MyNameIsLocalBranch:working-on-remote-branch 

once origin is configured:


$ git push origin MyNameIsLocalBranch:working-on-remote-branch  (git push origin local-name:remote-name)

Check what is going on in gitland and launch local version:

Update/pull from remote repo when when you start a new day cd into project – pull from origin the remote branch:

git pull origin working-on-remote-branch
nvm install 14.16.1
git status
npm install
npm start

[/su_expand]

Package.json / Package-lock.json

https://www.jetbrains.com/help/idea/resolve-conflicts.html#CRLF_warning

https://www.jetbrains.com/help/idea/resolving-conflicts.html

Resolve conflicts

Last modified: 08 March 2021

Depending on your version control system, conflicts may arise in different situations.

When you work in a team, you may come across a situation when somebody commits changes to a file you are currently working on. If these changes do not overlap (that is, changes were made to different lines of code), the conflicting files are merged automatically. However, if the same lines were affected, your version control system cannot randomly pick one side over the other, and asks you to resolve the conflict.

Conflicts may also arise when merging, rebasing or cherry-picking branches.

Non-Distributed Version Control Systems

When you try to edit a file that has a newer version on the server, IntelliJ IDEA informs you about that, showing a message popup in the editor:

conflicts warning

In this case, you should update your local version before changing the file, or merge changes later.

 

If you attempt to commit a file that has a newer repository version, the commit fails, and an error is displayed in the bottom right corner telling you that the file you are trying to commit is out of date.

 

The failed commit behavior is regulated by the Create changelist on failed commit list in the Version Control | Confirmation page of the Settings / Preferences dialog.

If you synchronize a file that already has local changes with a newer repository version committed by somebody else, a conflict occurs. The conflicting file gets the Merged with conflicts status. The file remains in the same changelist in the Local Changes view, but its name is highlighted in red. If the file is currently opened in the editor, the filename on the tab header is also highlighted in red.

Distributed Version Control Systems

Under distributed version control systems, such as Git and Mercurial, conflicts arise when a file you have committed locally has changes to the same lines of code as the latest upstream version and when you attempt to perform one of the following operations: pull, merge, rebase, cherry-pick, unstash, or apply patch.

If there are conflicts, these operations will fail and you will be prompted to accept the upstream version, prefer your version, or merge the changes manually:

IntelliJ IDEA: VCS operation conflicts dialog

The Conflicts dialog is triggered automatically when a conflict is detected on the Version Control level.

If you click Close in this dialog, or call a Git operation that leads to a merge conflict from command line, a Merge Conflicts node will appear in the Local Changes view with a link to resolve them:

The Merge Conflicts node in the Local Changes view

IntelliJ IDEA provides a tool for resolving conflicts locally. This tool consists of three panes:

  • The left page shows the read-only local copy
  • The right pane shows the read-only version checked in to the repository
  • The central pane shows a fully-functional editor where the results of merging and conflict resolving are displayed. Initially, the contents of this pane is the same as the base revision of the file, that is, the revision from which both conflicting versions are derived.

color coding in the conflict resolution tool

Resolve conflicts

Last modified: 08 March 2021

When you work in a team, you may come across a situation when somebody pushes changes to a file you are currently working on. If these changes do not overlap (that is, changes were made to different lines of code), the conflicting files are merged automatically. However, if the same lines were affected, Git cannot randomly pick one side over the other, and asks you to resolve the conflict.

In Git, conflicts may arise when you attempt to perform one of the following operations: pull, merge, rebase, cherry-pick, unstash changes or apply a patch. If there are conflicts, these operations will fail, and you will be prompted to accept the upstream version, prefer your version, or merge the changes:

Files Merged with Conflicts dialog

The Conflicts dialog is triggered automatically when a conflict is detected on the Git level.

If you click Close in this dialog, or call a Git operation that leads to a merge conflict from command line, a Merge Conflicts node will appear in the Local Changes view with a link to resolve them:

The Merge Conflicts node in the Local Changes view

IntelliJ IDEA provides a tool for resolving conflicts locally. This tool consists of three panes:

  • The left pane shows the read-only local copy
  • The right pane shows the read-only version checked in to the repository.
  • The central pane is a fully-functional editor where the results of resolving conflicts are displayed. Initially, the contents of this pane are the same as the base revision of the file, that is, the revision from which both conflicting versions are derived.

color coding in the conflict resolution tool

Resolve conflicts

  1. Click Merge in the Conflicts dialog, the Resolve link in the Local Changes view, or select the conflicting file in the editor and choose VCS | Git | Resolve Conflicts from the main menu.

  2. To automatically merge all non-conflicting changes, click (Apply All Non-Conflicting Changes) on the toolbar. You can also use the (Apply Non-Conflicting Changes from the Left Side) and (Apply Non-Conflicting Changes from the Right Side) to merge non-conflicting changes from the left/right parts of the dialog respectively.

  3. To resolve a conflict, you need to select which action to apply (accept or ignore ) to the left (local) and the right (repository) version, and check the resulting code in the central pane:

    Resolve conflicts

    You can also right-click a highlighted conflict in the central pane and use the commands from the context menu. The Resolve using Left and Resolve using Right commands provide a shortcut to accepting changes from one side and ignoring them from the other side respectively:

    the context menu of a conflicting change

    For simple conflicts (for example, if the beginning and the end of the same line have been modified in different file revisions), the Resolve simple conflicts button that allows merging the changes in one click becomes available.

    the Resolve Simple Conflicts button

    Such conflicts are not resolved with the Apply All Non-Conflicting Changes action since you must make sure that they are resolved properly.

     

    Note that the central pane is a fully-functional editor, so you can make changes to the resulting code directly in this dialog.

  4. It may also be useful to compare different versions to resolve a conflict. Use the toolbar button to invoke the list of options. Note that Base refers to the file version that the local and the repository versions originated from (initially displayed in the middle pane), while Middle refers to the resulting version.

  5. Review merge results in the central pane and click Apply.

Productivity tips

  • Apply non-conflicting changes automatically

    You can configure IntelliJ IDEA to always apply non-conflicting changes automatically instead of telling it to do so from the Merge dialog. To do this, select the Automatically apply non-conflicting changes option on the Tools | Diff Merge page of the IDE settings ⌘,.

  • Manage changes in the central pane

    You can manage changes in the central pane using the toolbar that appears when you hover the mouse cursor over a change marker in the gutter, and then click it. The toolbar is displayed together with a frame showing the previous contents of the modified line:the change toolbarFor example, when there are multiple non-conflicting changes, and you only need to skip one or two of them, it's easier to apply all of them simultaneously using the Apply all non-conflicting changes action, and then undo the unwanted ones using the Revert action from this toolbar.

Quite often, people working in a team and contributing to the same repository use different operating systems. This may result in problems with line ending, because Unix, Linux and MacOS us LF, and Windows uses CRLF to mark the end of a line.

IntelliJ IDEA displays the discrepancies in line endings in the Differences Viewer, so you can fix them manually. If you want Git to solve such conflicts automatically, you need to set the core.autocrlf attribute to true on Windows and to input on Linux and MacOS (for more details, see Dealing with line endings). You can change the configuration manually by running git config --global core.autocrlf true on Windows or git config --global core.autocrlf input on Linux and macOS.

However, IntelliJ IDEA can automatically analyze your configuration, warn you if you are about to commit CRLF into a remote repository, and suggest setting the core.autocrlf setting to true or input depending on your operating system.

To enable smart handling of LF and CRLF line separators, open the Settings/Preferences dialog ⌘,, and select the Version Control | Git node on the left. Enable the Warn if CRLF line separators are about to be committed option.

After you have enabled this option, IntelliJ IDEA will display the Line Separators Warning Dialog each time you are about to commit a file with CRLF separators, unless you have set any related Git attributes in the affected file (in this case, IntelliJ IDEA supposes that you clearly understand what you are doing and excludes this file from analysis).

In the Line Separators Warning Dialog, click one of the following:

  • Commit As Is to ignore the warning and commit a file with CRFL separators.
  • Fix and Commit to have the core.autocrlf attribute set to true or input depending on your operating system. As a result, CRLF line separators will be replaced with LF before the commit.

If, at a later time, you need to review how exactly conflicts were resolved during a merge, you can locate the required merge commit in the Log tab of the Git tool window ⌘9, select a file with conflicts in the Commit Details pane in the right, and click < or press ⌘D (see Review how changes were merged for details).

 


NPM creates a new package-lock.json – do you commits?

(e.g. my version of silvermine player had to be updated to match up with the updated package.json file from stage)

Yes, package-lock.json is intended to be checked into source control. If you're using npm 5+, you may see this notice on the command line: created a lockfile as package-lock.json. You should commit this file. According to npm help package-lock.json:

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

This file is intended to be committed into source repositories, and serves various purposes:

  • Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
  • Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.
  • To facilitate greater visibility of tree changes through readable source control diffs.
  • And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.

One key detail about package-lock.json is that it cannot be published, and it will be ignored if found in any place other than the toplevel package. It shares a format with npm-shrinkwrap.json, which is essentially the same file, but allows publication. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages.

If both package-lock.json and npm-shrinkwrap.json are present in the root of a package, package-lock.json will be completely ignored.

 


If software did not resolve package.json conflicts

 

Package.json – ALL INFO

https://docs.npmjs.com/cli/v6/configuring-npm/package-json


https://docs.npmjs.com/cli/v6/configuring-npm/package-locks

Resolving lockfile conflicts

Occasionally, two separate npm install will create package locks that cause merge conflicts in source control systems. As of npm@5.7.0, these conflicts can be resolved by manually fixing any package.json conflicts, and then running npm install [--package-lock-only] again. npm will automatically resolve any conflicts for you and write a merged package lock that includes all the dependencies from both branches in a reasonable tree. If --package-lock-only is provided, it will do this without also modifying your local node_modules/.

To make this process seamless on git, consider installing npm-merge-driver, which will teach git how to do this itself without any user interaction. In short: $ npx npm-merge-driver install -g will let you do this, and even works with pre-npm@5.7.0 versions of npm 5, albeit a bit more noisily. Note that if package.json itself conflicts, you will have to resolve that by hand and run npm install manually, even with the merge driver.


package-locks

An explanation of npm lockfiles

Table of contents

Description

Conceptually, the "input" to npm install is a package.json, while its "output" is a fully-formed node_modules tree: a representation of the dependencies you declared. In an ideal world, npm would work like a pure function: the same package.json should produce the exact same node_modules tree, any time. In some cases, this is indeed true. But in many others, npm is unable to do this. There are multiple reasons for this:

  • different versions of npm (or other package managers) may have been used to install a package, each using slightly different installation algorithms.
  • a new version of a direct semver-range package may have been published since the last time your packages were installed, and thus a newer version will be used.
  • A dependency of one of your dependencies may have published a new version, which will update even if you used pinned dependency specifiers (1.2.3 instead of ^1.2.3)
  • The registry you installed from is no longer available, or allows mutation of versions (unlike the primary npm registry), and a different version of a package exists under the same version number now.

As an example, consider package A:

 

{
  "name": "A",
  "version": "0.1.0",
  "dependencies": {
    "B": "<0.1.0"
  }
}

package B:

 

{
  "name": "B",
  "version": "0.0.1",
  "dependencies": {
    "C": "<0.1.0"
  }
}

and package C:

 

{
  "name": "C",
  "version": "0.0.1"
}

If these are the only versions of A, B, and C available in the registry, then a normal npm install A will install:

 

A@0.1.0
`-- B@0.0.1
    `-- C@0.0.1

However, if B@0.0.2 is published, then a fresh npm install A will install:

 

A@0.1.0
`-- B@0.0.2
    `-- C@0.0.1

assuming the new version did not modify B's dependencies. Of course, the new version of B could include a new version of C and any number of new dependencies. If such changes are undesirable, the author of A could specify a dependency on B@0.0.1. However, if A's author and B's author are not the same person, there's no way for A's author to say that he or she does not want to pull in newly published versions of C when B hasn't changed at all.

To prevent this potential issue, npm uses package-lock.json or, if present, npm-shrinkwrap.json. These files are called package locks, or lockfiles.

Whenever you run npm install, npm generates or updates your package lock, which will look something like this:

 

{
  "name": "A",
  "version": "0.1.0",
  ...metadata fields...
  "dependencies": {
    "B": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
      "integrity": "sha512-DeAdb33F+"
      "dependencies": {
        "C": {
          "version": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
        }
      }
    }
  }
}

This file describes an exact, and more importantly reproducible node_modules tree. Once it's present, any future installation will base its work off this file, instead of recalculating dependency versions off package.json.

The presence of a package lock changes the installation behavior such that:

  1. The module tree described by the package lock is reproduced. This means reproducing the structure described in the file, using the specific files referenced in "resolved" if available, falling back to normal package resolution using "version" if one isn't.
  2. The tree is walked and any missing dependencies are installed in the usual fashion.

If preshrinkwrap, shrinkwrap or postshrinkwrap are in the scripts property of the package.json, they will be executed in order. preshrinkwrap and shrinkwrap are executed before the shrinkwrap, postshrinkwrap is executed afterwards. These scripts run for both package-lock.json and npm-shrinkwrap.json. For example to run some postprocessing on the generated file:

 

"scripts": {
    "postshrinkwrap": "json -I -e \"this.myMetadata = $MY_APP_METADATA\""
  }
Using locked packages

Using a locked package is no different than using any package without a package lock: any commands that update node_modules and/or package.json's dependencies will automatically sync the existing lockfile. This includes npm install, npm rm, npm update, etc. To prevent this update from happening, you can use the --no-save option to prevent saving altogether, or --no-shrinkwrap to allow package.json to be updated while leaving package-lock.json or npm-shrinkwrap.json intact.

It is highly recommended you commit the generated package lock to source control: this will allow anyone else on your team, your deployments, your CI/continuous integration, and anyone else who runs npm install in your package source to get the exact same dependency tree that you were developing on. Additionally, the diffs from these changes are human-readable and will inform you of any changes npm has made to your node_modules, so you can notice if any transitive dependencies were updated, hoisted, etc.

Resolving lockfile conflicts

Occasionally, two separate npm install will create package locks that cause merge conflicts in source control systems. As of npm@5.7.0, these conflicts can be resolved by manually fixing any package.json conflicts, and then running npm install [--package-lock-only] again. npm will automatically resolve any conflicts for you and write a merged package lock that includes all the dependencies from both branches in a reasonable tree. If --package-lock-only is provided, it will do this without also modifying your local node_modules/.

To make this process seamless on git, consider installing npm-merge-driver, which will teach git how to do this itself without any user interaction. In short: $ npx npm-merge-driver install -g will let you do this, and even works with pre-npm@5.7.0 versions of npm 5, albeit a bit more noisily. Note that if package.json itself conflicts, you will have to resolve that by hand and run npm install manually, even with the merge driver.

See Also

 

DO NOT – Delete `package-lock.json` to Resolve Conflicts quickly

Yes it can have bad side effects, maybe not very often but for example you can have in package.json “moduleX”: “^1.0.0” and you used to have “moduleX”: “1.0.0” in package-lock.json.

By deleting package-lock.json and running npm install you could be updating to version 1.0.999 of moduleX without knowing about it and maybe they have created a bug or done a backwards breaking change (not following semantic versioning).

Anyway there is already a standard solution for it.

Fix the conflict inside package.json
Run: npm install –package-lock-only
https://docs.npmjs.com/cli/v7/configuring-npm/package-locks#resolving-lockfile-conflicts

package-lock.json – role

It stores an exact, versioned dependency tree rather than using starred versioning like package.json itself (e.g. 1.0.*). This means you can guarantee the dependencies for other developers or prod releases, etc. It also has a mechanism to lock the tree but generally will regenerate if package.json changes.

From the npm docs:

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

This file is intended to be committed into source repositories, and serves various purposes:

Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.

Provide a facility for users to “time-travel” to previous states of node_modules without having to commit the directory itself.

To facilitate greater visibility of tree changes through readable source control diffs.

And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.”

To answer jrahhali’s question below about just using the package.json with exact version numbers. Bear in mind that your package.json contains only your direct dependencies, not the dependencies of your dependencies (sometimes called nested dependencies). This means with the standard package.json you can’t control the versions of those nested dependencies, referencing them directly or as peer dependencies won’t help as you also don’t control the version tolerance that your direct dependencies define for these nested dependencies.

Even if you lock down the versions of your direct dependencies you cannot 100% guarantee that your full dependency tree will be identical every time. Secondly you might want to allow non-breaking changes (based on semantic versioning) of your direct dependencies which gives you even less control of nested dependencies plus you again can’t guarantee that your direct dependencies won’t at some point break semantic versioning rules themselves.

The solution to all this is the lock file which as described above locks in the versions of the full dependency tree. This allows you to guarantee your dependency tree for other developers or for releases whilst still allowing testing of new dependency versions (direct or indirect) using your standard package.json.

NB. The previous shrink wrap json did pretty much the same thing but the lock file renames it so that it’s function is clearer. If there’s already a shrink wrap file in the project then this will be used instead of any lock file.

 

Solving conflicts in package-lock.json

https://tkdodo.eu/blog/solving-conflicts-in-package-lock-json

One thing that can be costly when done wrong is solving conflicts in generated files, like package-lock.json. It usually happens when two branches add or update a dependency. The result of package-lock then changes, and whoever gets their PR merged to main first is the lucky one who avoided those conflicts. It's almost like a race.

So here you are, updating your PR with the base branch, and git shows you this huge amount of conflicts in package-lock.json. The conflicts in package.json are usually easily solved (if there even are any), so I think it is tempting to just delete package-lock.json and run npm install. After all, this will give you a brand new package-lock.json, which you can happily commit.

Why you should never delete package-lock.json

When you install a dependency for the first time, it is usually automatically added to your dependencies or devDependencies with ^version, which means "compatible with version, according to semver". You can try out what that means here.

Enter, for example, lodash as the package and ^4.2.1 as version, and you will see that you can get anything from 4.2.1 to 4.17.20 (the latest version)

semver calc

This is where package-lock.json comes into play. Upon installing, it will "lock" you in on the version that you just installed. So if 4.2.1 is the latest version at the moment of your install, this version will be written to package-lock and will, from there on, always be installed. Even if newer versions come out that are theoretically compatible with it.

This is important because it guarantees that every developer in the team will have the same version on their machine, and it is equally important for CI/CD. I would not want to ship a newer version to production than we tested with, even if it's just a patch version.

So when you delete package-lock.json, all those consistency goes out the window. Every node_module you depend on will be updated to the latest version it is theoretically compatible with. This means no major changes, but minors and patches. I believe this is bad for three reasons:

  1. It trusts that everyone strictly adheres to semantic versioning, and I sincerely doubt that this is the case. There is also no way to enforce this.

  2. Major version zero is exempt from the rules of semantic versioning. From

    the semver spec

    :

    Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.

Have a look at your package-lock.json and count how many dependencies with major version 0 you have. For this blog (made with gatsby) I have 362!

  1. This also applies to transitive dependencies. So even if you are using strict versions (without the ^), the libraries you are using do not.

If you delete package-lock.json now from any one of your projects and run npm install again, it will most certainly look completely different.

Will your app be fine? Maybe, maybe not. No one can tell. For me, this would usually mean: "regression test everything", which is certainly not what I have in mind when I am just solving a conflict.

What you can do instead

My usual approach was the following:

  • Solve the conflicts in package.json
  • Take package-lock.json from the base branch
  • run npm install again

This will then just re-install whatever changes we made in our branch. However, I recently learned about and even easier way:

npm can automatically detect conflicts in package-lock.json and resolve them for us. From the npm docs:

Occasionally, two separate npm install will create package locks that cause merge conflicts in source control systems. As of npm@5.7.0, these conflicts can be resolved by manually fixing any package.json conflicts, and then running npm install [–package-lock-only] again. npm will automatically resolve any conflicts for you and write a merged package lock that includes all the dependencies from both branches in a reasonable tree. If –package-lock-only is provided, it will do this without also modifying your local node_modules/.

This means that we can just keep the conflicts in the lock file. All we have to do is get package.json right, and npm will do the rest for us 🎉.

I wish I had known this sooner – it would've saved me some trouble.

Other ways to unset remote tracking

You don’t have to delete your local branch.

Simply delete the local branch that is tracking the remote branch:


git branch -d -r origin/

-r, –remotes tells git to delete the remote-tracking branch (i.e., delete the branch set to track the remote branch). This will not delete the branch on the remote repo!

See “Having a hard time understanding git-fetch”
https://stackoverflow.com/questions/1070496/having-a-hard-time-understanding-git-fetch

there’s no such concept of local tracking branches, only remote tracking branches.
So origin/master is a remote tracking branch for master in the origin repo

As mentioned in Dobes Vandermeer’s answer, you also need to reset the configuration associated to the local branch:


git config --unset branch..remote
git config --unset branch..merge
Remove the upstream information for .

If no branch is specified it defaults to the current branch.

That will make any push/pull completely unaware of origin/.


Set tracking branches for existing local branches

On the other hand, you may have chosen to work on a local branch and to set the upstream branch (or the remote tracking branch later on).

It is perfectly fine, but you will have to use the “git branch” in order to set the existing branch upstream branch.


$ git branch -u /

Let’s take the example of the “feature” branch that you just created to start working.

$ git checkout -b feature
Switched to a new branch ‘feature’

You created some commits in your branch, you want to set the tracking branch to be master.

$ git branch -u origin/master
Branch ‘feature’ set up to track remote branch ‘master’ from ‘origin’.

Great! You successfully set the upstream branch for your existing local branch.


Sorting out which branch is which – origin / pull / push

“origin” is not special
Just like the branch name “master” does not have any special meaning in Git, neither does “origin”. While “master” is the default name for a starting branch when you run git init which is the only reason it’s widely used, “origin” is the default name for a remote when you run git clone. If you run git clone -o booyah instead, then you will have booyah/master as your default remote branch.

Using the example of my copy of Puppet checked out from the upstream Git repository on Github.com…


$ git remote show origin
* remote origin
  Fetch URL: git://github.com/reductivelabs/puppet.git
  Push  URL: git://github.com/reductivelabs/puppet.git
  HEAD branch: master
  Remote branches:
    0.24.x                 tracked
    0.25.x                 tracked
    2.6.x                  tracked
    master                 tracked
    next                   tracked
    primordial-ooze        tracked
    reins-on-a-horse       tracked
    testing                tracked
    testing-17-march       tracked
    testing-18-march       tracked
    testing-2-april        tracked
    testing-2-april-midday tracked
    testing-20-march       tracked
    testing-21-march       tracked
    testing-24-march       tracked
    testing-26-march       tracked
    testing-29-march       tracked
    testing-31-march       tracked
    testing-5-april        tracked
    testing-9-april        tracked
    testing4268            tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Then if I were to execute the following:


$ git checkout -b local_2.6 -t origin/2.6.x 
Branch local_2.6 set up to track remote branch 2.6.x from origin.
Switched to a new branch 'local_2.6'

And finally re-run the git remote show origin command again I will then see the following down near the bottom:


  Local branches configured for 'git pull':
    local_2.6 merges with remote 2.6.x
    master    merges with remote master

Upstream shorthand

When you have a tracking branch set up, you can reference its upstream branch with the @{upstream} or @{u} shorthand. So if you’re on the master branch and it’s tracking origin/master, you can say something like git merge @{u} instead of git merge origin/master if you wish.


Tracking Branches

Checking out a local branch from a remote-tracking branch automatically creates what is called a “tracking branch” (and the branch it tracks is called an “upstream branch”). Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type git pull, Git automatically knows which server to fetch from and which branch to merge in.

When you clone a repository, it generally automatically creates a master branch that tracks origin/master. However, you can set up other tracking branches if you wish — ones that track branches on other remotes, or don’t track the master branch. The simple case is the example you just saw, running git checkout -b /. This is a common enough operation that Git provides the –track shorthand:


$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

In fact, this is so common that there’s even a shortcut for that shortcut. If the branch name you’re trying to checkout (a) doesn’t exist and (b) exactly matches a name on only one remote, Git will create a tracking branch for you:


$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

To set up a local branch with a different name than the remote branch, you can easily use the first version with a different local branch name:


$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

Now, your local branch sf will automatically pull from origin/serverfix.

If you already have a local branch and want to set it to a remote branch you just pulled down, or want to change the upstream branch you’re tracking, you can use the -u or –set-upstream-to option to git branch to explicitly set it at any time.


$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Note
Upstream shorthand

When you have a tracking branch set up, you can reference its upstream branch with the @{upstream} or @{u} shorthand. So if you’re on the master branch and it’s tracking origin/master, you can say something like git merge @{u} instead of git merge origin/master if you wish.

If you want to see what tracking branches you have set up, you can use the -vv option to git branch. This will list out your local branches with more information including what each branch is tracking and if your local branch is ahead, behind or both.


$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] Add forgotten brackets
  master    1ae2a45 [origin/master] Deploy index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] This should do it
  testing   5ea463a Try something new

So here we can see that our iss53 branch is tracking origin/iss53 and is “ahead” by two, meaning that we have two commits locally that are not pushed to the server. We can also see that our master branch is tracking origin/master and is up to date. Next we can see that our serverfix branch is tracking the server-fix-good branch on our teamone server and is ahead by three and behind by one, meaning that there is one commit on the server we haven’t merged in yet and three commits locally that we haven’t pushed. Finally we can see that our testing branch is not tracking any remote branch.

It’s important to note that these numbers are only since the last time you fetched from each server. This command does not reach out to the servers, it’s telling you about what it has cached from these servers locally. If you want totally up to date ahead and behind numbers, you’ll need to fetch from all your remotes right before running this. You could do that like this:


$ git fetch --all; git branch -vv

Pulling

While the git fetch command will fetch all the changes on the server that you don’t have yet, it will not modify your working directory at all. It will simply get the data for you and let you merge it yourself. However, there is a command called git pull which is essentially a git fetch immediately followed by a git merge in most cases. If you have a tracking branch set up as demonstrated in the last section, either by explicitly setting it or by having it created for you by the clone or checkout commands, git pull will look up what server and branch your current branch is tracking, fetch from that server and then try to merge in that remote branch.

Generally it’s better to simply use the fetch and merge commands explicitly as the magic of git pull can often be confusing.


Push Branch to Another Branch (different named branches)

In some cases, you may want to push your changes to another branch on the remote repository.

In order to push your branch to another branch, you may need to merge the remote branch to your current local branch.

In order to be merged, the tip of the remote branch cannot be behind the branch you are trying to push.

Before pushing, make sure to pull the changes from the remote branch and integrate them with your current local branch.

$ git pull (from remote branch)

$ git checkout my-feature (local branch)

$ git merge origin/feature (main project)

$ git push origin my-feature:feature  |  git push origin local-name:remote-name

Note : when merging the remote branch, you are merging your local branch with the upstream branch of your local repository.

 

In order to push your branch to another remote branch, use the “git push” command and specify the remote name, the name of your local branch as the name of the remote branch.

$ git push <remote> <local_branch>:<remote_name>

As an example, let’s say that you have created a local branch named “my-feature”.

$ git branch

  master
* my-feature
  feature

However, you want to push your changes to the remote branch named “feature” on your repository.

In order to push your branch to the “feature” branch, you would execute the following command

$ git push origin my-feature:feature

Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 513 bytes | 513.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/SCHKN/repo.git
   b1c4c91..9ae0aa6  my-feature -> feature

 


Origin

setting origin for local branch (different named branches)

Use the colon notation:

git push -u origin local_branch:remote_branch

 



More Origin notes

git remote show origin

origin is an alias on your system for a particular remote repository. It's not actually a property of that repository.

By doing

git push origin branchname

you're saying to push to the origin repository. There's no requirement to name the remote repository origin: in fact the same repository could have a different alias for another developer.

Remotes are simply an alias that store the URL of repositories. You can see what URL belongs to each remote by using

git remote -v

In the push command, you can use remotes or you can simply use a URL directly. An example that uses the URL:

git push git@github.com:git/git.git master

 


You can also specify -v, which shows you the URLs that Git has stored for the shortname to be used when reading and writing to that remote:

$ git remote -v

 


Set upstream branch – same name

Given a branch foo and a remote upstream:

As of Git 1.8.0:

git branch -u upstream/foo

Or, if local branch foo is not the current branch:

git branch -u upstream/foo foo

Or, if you like to type longer commands, these are equivalent to the above two:

git branch --set-upstream-to=upstream/foo

git branch --set-upstream-to=upstream/foo foo

As of Git 1.7.0 (before 1.8.0):

git branch --set-upstream foo upstream/foo

Notes:

  • All of the above commands will cause local branch foo to track remote branch foo from remote upstream.
  • The old (1.7.x) syntax is deprecated in favor of the new (1.8+) syntax. The new syntax is intended to be more intuitive and easier to remember.
  • Defining an upstream branch will fail when run against newly-created remotes that have not already been fetched. In that case, run git fetch upstream beforehand.

 


git branch --set-upstream-to, which can be used as follows, if you're on the branch my_branch:

git branch --set-upstream-to origin/my_branch

… or with the short option:

git branch -u origin/my_branch

This change, and its reasoning, is described in the release notes for git 1.8.0, release candidate 1:

It was tempting to say git branch --set-upstream origin/master, but that tells Git to arrange the local branch origin/master to integrate with the currently checked out branch, which is highly unlikely what the user meant. The option is deprecated; use the new --set-upstream-to (with a short-and-sweet -u) option instead.

 

 

 


A shortcut, which doesn't depend on remembering the syntax for git branch --set-upstream 1 is to do:

git push -u origin my_branch

… the first time that you push that branch. Or, to push to the current branch to a branch of the same name (handy for an alias):

git push -u origin HEAD

You only need to use -u once, and that sets up the association between your branch and the one at origin in the same way as git branch --set-upstream does.

Personally, I think it's a good thing to have to set up that association between your branch and one on the remote explicitly. It's just a shame that the rules are different for git push and git pull.


1 It may sound silly, but I very frequently forget to specify the current branch, assuming that's the default – it's not, and the results are most confusing

Update 2012-10-11: Apparently I'm not the only person who found it easy to get wrong! Thanks to VonC for pointing out that git 1.8.0 introduces the more obvious git branch --set-upstream-to, which can be used as follows, if you're on the branch my_branch:

git branch --set-upstream-to origin/my_branch

… or with the short option:

git branch -u origin/my_branch

This change, and its reasoning, is described in the release notes for git 1.8.0, release candidate 1:

It was tempting to say git branch --set-upstream origin/master, but that tells Git to arrange the local branch origin/master to integrate with the currently checked out branch, which is highly unlikely what the user meant. The option is deprecated; use the new --set-upstream-to (with a short-and-sweet -u) option instead.

 


When you're publishing a local branch – same names remote and local

Let's now look at the opposite scenario: you started a new local branch and now want to publish it on the remote for the first time:

$ git push -u origin dev

You can tell Git to track the newly created remote branch simply by using the -u flag with "git push".

When you decide at a later point in time

In cases when you simply forgot, you can set (or change) a tracking relationship for your current HEAD branch at any time:

$ git branch -u origin/dev

 

Push Branch To Remote – same names remote and local

In order to push a Git branch to remote, you need to execute the “git push” command and specify the remote as well as the branch name to be pushed.

$ git push <remote> <branch>

For example, if you need to push a branch named “feature” to the “origin” remote, you would execute the following query

$ git push origin feature
git push branch to remote
git push branch to remote

If you are not already on the branch that you want to push, you can execute the “git checkout” command to switch to your branch.

If your upstream branch is not already created, you will need to create it by running the “git push” command with the “-u” option for upstream.

git push upstream branch to remote
git push upstream branch to remote
$ git push -u origin feature

Congratulations, you have successfully pushed your branch to your remote!

 

Scroll to Top