diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py
index 51e33e8b1ddba8dc4103a054fd8bb625982f240c..11a3eace31431ea790d2d66bc8b34eec90b34155 100644
--- a/buildstream/_frontend/cli.py
+++ b/buildstream/_frontend/cli.py
@@ -681,11 +681,12 @@ def checkout(app, element, location, force, deps, integrate, hardlinks, tar):
 @click.option('--tar', 'tar', default=False, is_flag=True,
               help='Create a tarball from the element\'s sources instead of a '
                    'file tree.')
-@click.argument('element',
-                type=click.Path(readable=False))
+@click.option('--include-build-scripts', 'build_scripts', is_flag=True)
+@click.argument('element', type=click.Path(readable=False))
 @click.argument('location', type=click.Path())
 @click.pass_obj
-def source_checkout(app, element, location, force, deps, fetch_, except_, tar):
+def source_checkout(app, element, location, force, deps, fetch_, except_,
+                    tar, build_scripts):
     """Checkout sources of an element to the specified location
     """
     with app.initialized():
@@ -695,7 +696,8 @@ def source_checkout(app, element, location, force, deps, fetch_, except_, tar):
                                    deps=deps,
                                    fetch=fetch_,
                                    except_targets=except_,
-                                   tar=tar)
+                                   tar=tar,
+                                   include_build_scripts=build_scripts)
 
 
 ##################################################################
diff --git a/buildstream/_stream.py b/buildstream/_stream.py
index 3aa8a2de749c0a01105431a40ed30fdd2dda9f5c..7e617a74f787ca131e1e413ca316b94cb1df4b17 100644
--- a/buildstream/_stream.py
+++ b/buildstream/_stream.py
@@ -440,7 +440,8 @@ class Stream():
                         deps='none',
                         fetch=False,
                         except_targets=(),
-                        tar=False):
+                        tar=False,
+                        include_build_scripts=False):
 
         self._check_location_writable(location, force=force, tar=tar)
 
@@ -456,10 +457,8 @@ class Stream():
 
         # Stage all sources determined by scope
         try:
-            if tar:
-                self._create_source_tarball(location, elements)
-            else:
-                self._write_element_sources(location, elements)
+            self._source_checkout(elements, location, force, deps, fetch,
+                                  except_targets, tar, include_build_scripts)
         except BstError as e:
             raise StreamError("Error while writing sources"
                               ": '{}'".format(e), detail=e.detail, reason=e.reason) from e
@@ -748,7 +747,7 @@ class Stream():
             ]
 
             self._write_element_sources(os.path.join(tempdir, "source"), elements)
-            self._write_build_script(tempdir, elements)
+            self._write_master_build_script(tempdir, elements)
             self._collect_sources(tempdir, tar_location,
                                   target.normal_name, compression)
 
@@ -1135,6 +1134,7 @@ class Stream():
     # Helper function for source_checkout()
     def _source_checkout(self, elements,
                          location=None,
+                         force=False,
                          deps='none',
                          fetch=False,
                          except_targets=(),
@@ -1205,17 +1205,29 @@ class Stream():
                 os.makedirs(element_source_dir)
                 element._stage_sources_at(element_source_dir)
 
-    # Create a tarball containing the sources of each element in elements
-    def _create_source_tarball(self, directory, elements):
-        with tarfile.open(name=directory, mode='w') as tf:
-            with TemporaryDirectory() as tmpdir:
-                self._write_element_sources(tmpdir, elements)
-                for item in os.listdir(tmpdir):
-                    file_to_add = os.path.join(tmpdir, item)
+    # Create a tarball from the content of directory
+    def _create_tarball(self, directory, tar_name):
+        try:
+            with tarfile.open(name=tar_name, mode='w') as tf:
+                for item in os.listdir(str(directory)):
+                    file_to_add = os.path.join(directory, item)
                     tf.add(file_to_add, arcname=item)
+        except OSError as e:
+            # If we have a partially constructed tar file, clean up after ourselves
+            try:
+                os.remove(tar_name)
+            except OSError:
+                pass
+            raise StreamError("Failed to create tar archive: {}".format(e)) from e
+
+    # Write all the build_scripts for elements in the directory location
+    def _write_build_scripts(self, location, elements):
+        for element in elements:
+            self._write_element_script(location, element)
+        self._write_master_build_script(location, elements)
 
     # Write a master build script to the sandbox
-    def _write_build_script(self, directory, elements):
+    def _write_master_build_script(self, directory, elements):
 
         module_string = ""
         for element in elements:
diff --git a/tests/frontend/source_checkout.py b/tests/frontend/source_checkout.py
index 5aebacce7c43395e18826571bf9ca81ee747836c..193dc4ab1b91ae727b7b9ed2108e0cd7a0f806ec 100644
--- a/tests/frontend/source_checkout.py
+++ b/tests/frontend/source_checkout.py
@@ -154,3 +154,38 @@ def test_source_checkout_fetch(datafiles, cli, fetch):
         assert os.path.exists(os.path.join(checkout, 'remote-import-dev', 'pony.h'))
     else:
         result.assert_main_error(ErrorDomain.PIPELINE, 'uncached-sources')
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_source_checkout_build_scripts(cli, tmpdir, datafiles):
+    project_path = os.path.join(datafiles.dirname, datafiles.basename)
+    element_name = 'source-bundle/source-bundle-hello.bst'
+    normal_name = 'source-bundle-source-bundle-hello'
+    checkout = os.path.join(str(tmpdir), 'source-checkout')
+
+    args = ['source-checkout', '--include-build-scripts', element_name, checkout]
+    result = cli.run(project=project_path, args=args)
+    result.assert_success()
+
+    # There sould be a script for each element (just one in this case) and a top level build script
+    expected_scripts = ['build.sh', 'build-' + normal_name]
+    for script in expected_scripts:
+        assert script in os.listdir(checkout)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_source_checkout_tar_buildscripts(cli, tmpdir, datafiles):
+    project_path = os.path.join(datafiles.dirname, datafiles.basename)
+    element_name = 'source-bundle/source-bundle-hello.bst'
+    normal_name = 'source-bundle-source-bundle-hello'
+    tar_file = os.path.join(str(tmpdir), 'source-checkout.tar')
+
+    args = ['source-checkout', '--include-build-scripts', '--tar', element_name, tar_file]
+    result = cli.run(project=project_path, args=args)
+    result.assert_success()
+
+    expected_scripts = ['build.sh', 'build-' + normal_name]
+
+    with tarfile.open(tar_file, 'r') as tf:
+        for script in expected_scripts:
+            assert script in tf.getnames()