Changing on which repository the VM thinks I am working

This conversation started in a support chat with ‘Viktor’. What it boils down to is this:

Usually, when I am working locally in a directory that is a git repository with a .git dir, when I do a git status it gives me info about this repo

But when I clone a repository on the Bitrise VM in a “script step” by just doing git clone git@some.url:some-repo, then do my thing, delete it again and change (cd) into the directory created by the Bitrise “git clone” step with a .git dir the VM still seems to “think” I work on some-repo.

This results in mix ups in further steps because the fetch and push url of the repository the VM thinks I am in changed to the repository url from the “script step”. BUT the branches the output of echo "$(git remote show origin)" shows are the branches of my original Bitrise “git clone” step repository. Also these banches are shown as stale.

Somehow I need a switch back to my code repository from the Bitrise “git clone” step after a git clone in a “script step”. How do I do that? I hope I made myself clear.

edit: problem was sitting in front of the screen, I overwrote one .git directory with another .git directory, so nothing to see here, move along.

So, what you have to know about the “working directory” handling of Bitrise (CLI):

  1. Every step runs in a new shell, which means that if you run a Script step in which you cd into a directory, you will be in that dir until the step finishes; the cd in the Script step won’t affect the working directory of other steps. Think about this as if you would run the build steps one by one, as separate scripts. If you run bash script1.sh which changes the working directory, and then when the script1.sh script finishes you run bash script2.sh the working directory change in script1.sh won’t affect script2.sh, only if you run script2.sh from script1.sh, but not if you run them one by one, after each other, separately (which is pretty much how build steps run, one by one, separately).
  2. It’s possible to change the working directory for other steps, by overwriting the BITRISE_SOURCE_DIR env var through envman. The easiest way to do this is to use the Change Working Directory for subsequent Steps step.

Couple of example

One script step

If you have a single Script step in which you want to change the working directory, but you don’t need to change the working directory for other/subsequent steps, then there’s absolutely nothing special here.

cd ./a/sub/dir

pwd

As you would expect pwd will print the path including ./a/sub/dir, and the rest of the Script will also be in ./a/sub/dir. Nothing special, just like what you would expect.

Two script steps

If you cd into a sub dir in one step (e.g. a Script step) and then you run another step, the cd from the first step won’t apply for the second one. Example:

- script@1.1.3:
    inputs:
    - content: |-
        #!/bin/bash

        cd ./a/sub/dir
        pwd
- script@1.1.3:
    inputs:
    - content: |-
        #!/bin/bash

        pwd

pwd in the first step will print what you expect, the path including ./a/sub/dir. But the pwd in the second step will print that you’re in the original working directory, as the cd change does not affect other steps, only the one where you cd!

Change the working directory of subsequent steps using the Change Working Directory step

Using the example above, if you permanently want to change the working directory to ./a/sub/dir, you can use the Change Working Directory for subsequent Steps step to do that:

- change-workdir@1.0.1:
    inputs:
    - path: ./a/sub/dir
- script@1.1.3:
    inputs:
    - content: |-
        #!/bin/bash

        pwd

The pwd in the second, Script step will print the path including a/sub/dir, and every other step after the Change Workdir step will have the working directory “a/sub/dir”.

The only issue with this is, how can you change back to the original workdir?

Change back to the original working directory

You can change back to the original work dir with adding another Change Working Directory for subsequent Steps step.

You can of course specify a “path” for the second Change Working Directory for subsequent Steps step like ./../../.., to move the working directory 3 levels up for example, which would work in this example case, when you switch 3 dirs down (a/sub/dir), ../../.. should get you back to the original work dir.

This might work, but not exactly future proof. A way better solution is to save the original working directory into an environment variable, so that you will be able to reference that anywhere in your configs!

The easiest way is to do this with an App Env Var:

format_version: 1.3.1
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
app:
  envs:
  - ORIG_WORK_DIR: $BITRISE_SOURCE_DIR
workflows:
  primary:
    steps:
    - change-workdir@1.0.1:
        inputs:
        - path: $ORIG_WORK_DIR/a/sub/dir
    - script@1.1.3:
        inputs:
        - content: |-
            #!/bin/bash

            pwd
    - change-workdir@1.0.1:
        inputs:
        - path: $ORIG_WORK_DIR
    - script@1.1.3:
        inputs:
        - content: |-
            #!/bin/bash

            pwd

This configuration will do exactly what you expect, the first change workdir step will change into ./a/sub/dir, and every step after that will start in a/sub/dir, until the second change workdir step, which will change the path back to the original working directory (your source code root).

This works because app env vars are evaluated before any workflow or step, so the value of the source dir path (BITRISE_SOURCE_DIR) env var will be assigned to ORIG_WORK_DIR and not the $BITRISE_SOURCE_DIR variable which would change during the build.

More info about environment and input processing: http://devcenter.bitrise.io/bitrise-cli/most-important-concepts/#availability-order-of-environment-variables

If you have any questions, just let us know!

Happy Building! :slight_smile: